严智鑫
2024-07-05 c7093edbf1fb3c91107c457ea13935305e1a9458
Merge branch 'master' of http://10.153.19.25:10101/r/HangZhouMes

# Conflicts:
# hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/service/impl/GlassInfoServiceImpl.java
# hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/CacheGlassTask.java
# hangzhoumesParent/moduleService/CacheGlassModule/src/main/resources/application-prod.yml
# hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/impl/DownStorageCageServiceImpl.java
# hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownCacheGlassTask.java
卧室缓存 推送数据改为一个
131个文件已修改
1 文件已重命名
45个文件已添加
22个文件已删除
15206 ■■■■■ 已修改文件
JsonFile/PlcCacheVerticalGlass.json 430 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JsonFile/PlcdownGlass.json 502 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/auto-imports.d.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/package-lock.json 1349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/package.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/LanguageMixin.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/en.js 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/i18n.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/index.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/locales/en-US.json 575 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/locales/zh-CN.json 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/zh.js 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/layout/MainErpView.vue 182 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/main.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/router/index.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Caching/cachingbefore.vue 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Caching/cachingun.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/GlassStorage/MaterialRackManagement.vue 668 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Identify/identify.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/LoginView.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/PurchaseReturn/purchaseReturn.vue 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/PurchaseReturn/purchaseStorage.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/RegisterView.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Returns/returns.vue 146 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Slicecage/slicecage.vue 1304 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/StockBasicData/stockBasicData.vue 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/StockBasicData/stockBasicDatatwo.vue 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/Landingindication.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/Landingindicationtwo.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/UnLoadGlass/loadmachinerack.vue 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/User/permissions.vue 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/User/rolelist.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/User/userlist.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/vite.config.js 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/JsonFile/PlcCacheVerticalGlass.json 430 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/JsonFile/PlcdownGlass.json 502 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/base/entity/BigStorageCageBaseInfo.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/common/config/Const.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/controller/DamageController.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/entity/Damage.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/mapper/DamageMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/service/DamageService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/service/impl/DamageServiceImpl.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/entity/GlassInfo.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/entity/OptimizeGlassinfo.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/mapper/GlassInfoMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/service/impl/GlassInfoServiceImpl.java 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/controller/OrderController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Order.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Orderdetail.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Orders.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrderMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrderdetailMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrdersMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/xml/OrderMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/service/OrdersService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/service/impl/OrdersServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/controller/ReportingWorkController.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeDetail.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeLayout.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeProject.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/ReportingWork.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/request/AwaitingRepair.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/request/Reportingdamage.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/OptimizeLayoutMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/ReportingWorkMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/request/AwaitingRepairMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/request/ReportingDamageMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/OptimizeLayoutService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/OptimizeProjectService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/ReportingWorkService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/OptimizeLayoutServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/OptimizeProjectServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/ReportingWorkServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/entity/TemperingGlassInfo.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/mapper/TemperingGlassInfoMapper.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/tools/CodeGet.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/tools/DatabaseDesignDocUtil.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/uppattenusage/entity/UpPattenUsage.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/controller/WorkAssignmentController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/entity/WorkAssignment.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/mapper/WorkAssignmentMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/mapper/xml/WorkAssignmentMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/service/WorkAssignmentService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/service/impl/WorkAssignmentServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/resources/mapper/TemperingGlassInfoMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/controller/SysMenuController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/controller/SysRoleController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/userinfo/controller/SysUserController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/userinfo/service/impl/SysUserServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/pom.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/entity/EdgStorageCage.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/entity/EdgStorageCageDetails.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/service/EdgStorageCageService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/service/impl/EdgStorageCageDetailsServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/CacheGlassTask.java 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/resources/application-prod.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageDetailsController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageCage.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageCageDetails.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageDTO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/dto/SlotSequenceDTO.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/dto/TemperingLayoutDTO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/mapper/BigStorageCageDetailsMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageDetailsService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageServiceImpl.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/entity/BigStorageCageFeedTask.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/entity/BigStorageCageOutTask.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/mapper/BigStorageCageFeedTaskMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/mapper/BigStorageCageOutTaskMapper.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/BigStorageCageFeedTaskService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/BigStorageCageOutTaskService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageFeedTaskServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageOutTaskServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/common/S7object.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/controller/DamageController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/entity/Damage.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/service/DamageService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/controller/TaskCacheController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/entity/TaskCache.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/mapper/TaskCacheMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/service/TaskCacheService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/service/impl/TaskCacheServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/controller/GlassInfoController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/mapper/GlassInfoMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/service/GlassInfoService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/service/impl/GlassInfoServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcSlicecage.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcStorageCageTask.java 600 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/controller/TemperingGlassInfoController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/entity/TemperingGlassInfo.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/mapper/TemperingGlassInfoMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/service/TemperingGlassInfoService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/service/impl/TemperingGlassInfoServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/JsonFile/PlcCacheVerticalGlass.json 430 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-cz.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-dev.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-prod.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageDetailsMapper.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageFeedTaskMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageOutTaskMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/test/java/com/mes/CacheVerticalGlassModuleApplicationTest.java 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/engineering/entity/Engineering.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/engineering/entity/OptimizeEngineering.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/uppattenusage/entity/OptimizeUpPattenUsage.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/uppattenusage/service/impl/UpPattenUsageServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/workstation/entity/UpWorkstation.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/workstation/mapper/LoadGlassMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-cz.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-dev.yml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-prod.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/test/java/com/mes/ApplicationTest.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/LoadGlassModule/src/test/java/com/mes/LoadGlassModuleApplicationTest.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcScreenTask.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcTemperingGlassTask.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-cz.yml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-dev.yml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-prod.yml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/test/java/com/mes/TemperingApplicationTest.java 120 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/AppRunnerConfig.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/common/S7object.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/controller/DownGlassTaskController.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/entity/DownGlassInfo.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/entity/DownGlassTask.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/mapper/DownGlassInfoMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/DownGlassInfoService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/impl/DownGlassInfoServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/impl/DownGlassTaskServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/controller/DownStorageCageDetailsController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/entity/DownStorageCage.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/entity/DownStorageCageDetails.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/mapper/DownStorageCageDetailsMapper.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/DownStorageCageDetailsService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/DownStorageCageService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/impl/DownStorageCageDetailsServiceImpl.java 155 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/impl/DownStorageCageServiceImpl.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstation.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstationTask.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstionAndDownGlassinfo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/dto/DownGlassInfoDTO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownCacheGlassTask.java 293 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownLoadCacheGlassTask.java 520 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/JsonFile/PlcdownGlass.json 502 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application-cz.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application-prod.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application.yml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/mapper/DownGlassInfoMapper.xml 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/mapper/DownStorageCageDetailsMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/test/java/mes/UnloadGlassModuleApplicationTest.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JsonFile/PlcCacheVerticalGlass.json
@@ -1,57 +1,377 @@
{
  "plcAddressBegin":"DB.0",
  "plcAddressLenght":"72",
  "dataType":"word",
  "parameteInfor":[
    {
      "codeId": "D01Request",
      "addressIndex":"0",
      "addressLenght":"2",
      "ratio":"1",
      "unit":"m/min"
    },
    {
      "codeId": "D01ID1",
      "addressIndex":"2",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04Request",
      "addressIndex":"8",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04ID1",
      "addressIndex":"10",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D02Go",
      "addressIndex":"20",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D05Go",
      "addressIndex":"22",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ,
    {
      "codeId": "DeviceStatus",
      "addressIndex":"70",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ]
    "plcAddressBegin": "DB14.0",
    "plcAddressLenght": "938",
    "dataType": "word",
    "parameteInfor": [{
            "codeId": "D01ID",
            "addressIndex": "0",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D02ID",
            "addressIndex": "32",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID1",
            "addressIndex": "64",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID2",
            "addressIndex": "96",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID3",
            "addressIndex": "128",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID4",
            "addressIndex": "160",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID5",
            "addressIndex": "192",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID6",
            "addressIndex": "224",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ID",
            "addressIndex": "256",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID1",
            "addressIndex": "288",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID2",
            "addressIndex": "328",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID3",
            "addressIndex": "352",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID4",
            "addressIndex": "384",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID5",
            "addressIndex": "416",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID6",
            "addressIndex": "448",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID1",
            "addressIndex": "480",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID2",
            "addressIndex": "512",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID3",
            "addressIndex": "544",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID4",
            "addressIndex": "576",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID5",
            "addressIndex": "608",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID6",
            "addressIndex": "640",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID1",
            "addressIndex": "672",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID2",
            "addressIndex": "704",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID3",
            "addressIndex": "736",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID4",
            "addressIndex": "768",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID5",
            "addressIndex": "800",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID6",
            "addressIndex": "832",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ToMES",
            "addressIndex": "874",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ToMES",
            "addressIndex": "876",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D01ToMES",
            "addressIndex": "878",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ToMES",
            "addressIndex": "880",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD03",
            "addressIndex": "888",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD05",
            "addressIndex": "890",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToPLC",
            "addressIndex": "892",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport1",
            "addressIndex": "914",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport2",
            "addressIndex": "916",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport3",
            "addressIndex": "918",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport4",
            "addressIndex": "920",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport5",
            "addressIndex": "922",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport6",
            "addressIndex": "924",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport1",
            "addressIndex": "926",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport2",
            "addressIndex": "928",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport3",
            "addressIndex": "930",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport4",
            "addressIndex": "932",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport5",
            "addressIndex": "934",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport6",
            "addressIndex": "936",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "deviceState",
            "addressIndex": "864",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01State",
            "addressIndex": "866",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02State",
            "addressIndex": "868",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03State",
            "addressIndex": "870",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05State",
            "addressIndex": "872",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD01",
            "addressIndex": "894",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD04",
            "addressIndex": "896",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        }
    ]
}
JsonFile/PlcdownGlass.json
@@ -1,362 +1,144 @@
{
  "plcAddressBegin": "DB100.0",
  "plcAddressLenght": "142",
  "dataType": "word",
  "parameteInfor": [
    {
      "codeId": "RequestWord",
      "addressIndex": "0",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ID",
      "addressIndex": "2",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskRequestWord",
      "addressIndex": "4",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ID",
      "addressIndex": "6",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskRequestWord",
      "addressIndex": "8",
      "addressLenght": "2"
    },
    {
      "codeId": "G011ID",
      "addressIndex": "10",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "12",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "14",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "16",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "18",
      "addressLenght": "2"
    },
    {
      "codeId": "MESSendingWord",
      "addressIndex": "20",
      "addressLenght": "2"
    },
    {
      "codeId": "InputGrid",
      "addressIndex": "22",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputGrid",
      "addressIndex": "24",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputID",
      "addressIndex": "26",
      "addressLenght": "2"
    },
    {
      "codeId": "FrontOrRearLowerSlice",
      "addressIndex": "28",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "30",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskReply",
      "addressIndex": "32",
      "addressLenght": "2"
    },
    {
      "codeId": "G06Rack",
      "addressIndex": "34",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskReply",
      "addressIndex": "36",
      "addressLenght": "2"
    },
    {
      "codeId": "G11Rack",
      "addressIndex": "38",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "40",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "42",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "44",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "46",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "48",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "50",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "52",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "54",
      "addressLenght": "2"
    },
    {
      "codeId": "MESTaskState",
      "addressIndex": "56",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "58",
      "addressLenght": "2"
    },
    {
      "codeId": "AlarmState",
      "addressIndex": "60",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm1",
      "addressIndex": "62",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm2",
      "addressIndex": "64",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm3",
      "addressIndex": "66",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm4",
      "addressIndex": "68",
      "addressLenght": "2"
    },
    {
      "codeId": "neirong",
      "addressIndex": "70",
      "addressLenght": "2"
    },
    {
      "codeId": "device",
      "addressIndex": "72",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "74",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "76",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut1",
      "addressIndex": "78",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut2",
      "addressIndex": "80",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut3",
      "addressIndex": "82",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut4",
      "addressIndex": "84",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut5",
      "addressIndex": "86",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut6",
      "addressIndex": "88",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut7",
      "addressIndex": "90",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "92",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "94",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "96",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "98",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "100",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ActionState",
      "addressIndex": "102",
      "addressLenght": "2"
    },
    {
      "codeId": "G05ActionState",
      "addressIndex": "104",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ActionState",
      "addressIndex": "106",
      "addressLenght": "2"
    },
    {
      "codeId": "G07ActionState",
      "addressIndex": "108",
      "addressLenght": "2"
    },
    {
      "codeId": "G08ActionState",
      "addressIndex": "110",
      "addressLenght": "2"
    },
    {
      "codeId": "G09ActionState",
      "addressIndex": "112",
      "addressLenght": "2"
    },
    {
      "codeId": "G10ActionState",
      "addressIndex": "114",
      "addressLenght": "2"
    },
    {
      "codeId": "G11ActionState",
      "addressIndex": "116",
      "addressLenght": "2"
    },
    {
      "codeId": "G12ActionState",
      "addressIndex": "118",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ActionState",
      "addressIndex": "120",
      "addressLenght": "2"
    },
    {
      "codeId": "G04IDS",
      "addressIndex": "122",
      "addressLenght": "2"
    },
    {
      "codeId": "G05IDS",
      "addressIndex": "124",
      "addressLenght": "2"
    },
    {
      "codeId": "G06IDS",
      "addressIndex": "126",
      "addressLenght": "2"
    },
    {
      "codeId": "G07IDS",
      "addressIndex": "128",
      "addressLenght": "2"
    },
    {
      "codeId": "G08IDS",
      "addressIndex": "130",
      "addressLenght": "2"
    },
    {
      "codeId": "G09IDS",
      "addressIndex": "132",
      "addressLenght": "2"
    },
    {
      "codeId": "G10IDS",
      "addressIndex": "134",
      "addressLenght": "2"
    },
    {
      "codeId": "G11IDS",
      "addressIndex": "136",
      "addressLenght": "2"
    },
    {
      "codeId": "G12IDS",
      "addressIndex": "138",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ID",
      "addressIndex": "140",
      "addressLenght": "2"
    }
  ]
    "plcAddressBegin": "DB11.0",
    "plcAddressLenght": "92",
    "dataType": "word",
    "parameteInfor": [
        {
            "codeId": "requestWord",
            "addressIndex": "0",
            "addressLenght": "2"
        },
        {
            "codeId": "requestID",
            "addressIndex": "2",
            "addressLenght": "30"
        },
        {
            "codeId": "currentCell",
            "addressIndex": "32",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus08",
            "addressIndex": "36",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus06",
            "addressIndex": "40",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus11",
            "addressIndex": "42",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus13",
            "addressIndex": "44",
            "addressLenght": "2"
        },
        {
            "codeId": "G04_error_status",
            "addressIndex": "48",
            "addressLenght": "2"
        },
        {
            "codeId": "G05_error_status",
            "addressIndex": "50",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_error_status",
            "addressIndex": "52",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "54",
            "addressLenght": "2"
        },
        {
            "codeId": "G08_error_status",
            "addressIndex": "56",
            "addressLenght": "2"
        },
        {
            "codeId": "G09_error_status",
            "addressIndex": "58",
            "addressLenght": "2"
        },
        {
            "codeId": "G10_error_status",
            "addressIndex": "60",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_error_status",
            "addressIndex": "62",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "64",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_error_status",
            "addressIndex": "66",
            "addressLenght": "2"
        },
        {
            "codeId": "confirmationWord",
            "addressIndex": "72",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_prohibit_film_production",
            "addressIndex": "74",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_prohibit_film_production",
            "addressIndex": "76",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_prohibit_film_production",
            "addressIndex": "78",
            "addressLenght": "2"
        },
        {
            "codeId": "Glass_width",
            "addressIndex": "80",
            "addressLenght": "2"
        },
        {
            "codeId": "Glass_height",
            "addressIndex": "82",
            "addressLenght": "2"
        },
        {
            "codeId": "Glass_thickness",
            "addressIndex": "84",
            "addressLenght": "2"
        },
        {
            "codeId": "Start_cell",
            "addressIndex": "86",
            "addressLenght": "2"
        },
        {
            "codeId": "End_cell",
            "addressIndex": "88",
            "addressLenght": "2"
        },
        {
            "codeId": "task_type",
            "addressIndex": "90",
            "addressLenght": "2"
        }
    ]
}
UI-Project/auto-imports.d.ts
New file
@@ -0,0 +1,9 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
  const useI18n: typeof import('vue-i18n')['useI18n']
}
UI-Project/package-lock.json
@@ -11,6 +11,8 @@
        "@element-plus/icons-vue": "^2.1.0",
        "@vue-macros/reactivity-transform": "^0.3.23",
        "axios": "^1.6.8",
        "chart.js": "^4.4.3",
        "echarts": "^5.5.0",
        "element-plus": "^2.4.0",
        "moment": "^2.30.1",
        "pinia": "^2.1.6",
@@ -18,7 +20,8 @@
        "sortablejs": "^1.15.1",
        "sweetalert2": "^11.10.7",
        "vue": "^3.3.4",
        "vue-i18n": "^9.13.1",
        "vue-draggable-plus": "^0.5.0",
        "vue-i18n": "^9.10.1",
        "vue-router": "^4.2.4",
        "vxe-table": "^4.5.15",
        "xe-utils": "^3.5.14",
@@ -26,9 +29,19 @@
      },
      "devDependencies": {
        "@types/sortablejs": "^1.15.7",
        "@vitejs/plugin-vue": "^4.3.4",
        "@vitejs/plugin-vue": "^4.6.2",
        "http-proxy-middleware": "^3.0.0",
        "unplugin-auto-import": "^0.17.6",
        "vite": "^4.4.9"
      }
    },
    "node_modules/@antfu/utils": {
      "version": "0.7.8",
      "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.8.tgz",
      "integrity": "sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==",
      "dev": true,
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/@babel/helper-string-parser": {
@@ -87,348 +100,12 @@
        "vue": "^3.2.0"
      }
    },
    "node_modules/@esbuild/android-arm": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/android-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/android-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/darwin-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/darwin-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/freebsd-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/freebsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-arm": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-ia32": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
      "cpu": [
        "ia32"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-loong64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
      "cpu": [
        "loong64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-mips64el": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
      "cpu": [
        "mips64el"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-ppc64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
      "cpu": [
        "ppc64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-riscv64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
      "cpu": [
        "riscv64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-s390x": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
      "cpu": [
        "s390x"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/netbsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "netbsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/openbsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "openbsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/sunos-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "sunos"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-ia32": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
      "cpu": [
        "ia32"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
@@ -498,6 +175,46 @@
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
    },
    "node_modules/@kurkle/color": {
      "version": "0.3.2",
      "resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.2.tgz",
      "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
    },
    "node_modules/@nodelib/fs.scandir": {
      "version": "2.1.5",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.stat": "2.0.5",
        "run-parallel": "^1.1.9"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.stat": {
      "version": "2.0.5",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.walk": {
      "version": "1.2.8",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.scandir": "2.1.5",
        "fastq": "^1.6.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@popperjs/core": {
      "name": "@sxzz/popperjs-es",
      "version": "2.11.7",
@@ -509,9 +226,9 @@
      }
    },
    "node_modules/@rollup/pluginutils": {
      "version": "5.0.5",
      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
      "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
      "version": "5.1.0",
      "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
      "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
      "dependencies": {
        "@types/estree": "^1.0.0",
        "estree-walker": "^2.0.2",
@@ -566,10 +283,9 @@
      }
    },
    "node_modules/@types/sortablejs": {
      "version": "1.15.7",
      "resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.7.tgz",
      "integrity": "sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==",
      "dev": true
      "version": "1.15.8",
      "resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.8.tgz",
      "integrity": "sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg=="
    },
    "node_modules/@types/web-bluetooth": {
      "version": "0.0.16",
@@ -577,15 +293,15 @@
      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
    },
    "node_modules/@vitejs/plugin-vue": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.4.0.tgz",
      "integrity": "sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==",
      "version": "4.6.2",
      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
      "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
      "dev": true,
      "engines": {
        "node": "^14.18.0 || >=16.0.0"
      },
      "peerDependencies": {
        "vite": "^4.0.0",
        "vite": "^4.0.0 || ^5.0.0",
        "vue": "^3.2.25"
      }
    },
@@ -823,9 +539,9 @@
      }
    },
    "node_modules/acorn": {
      "version": "8.10.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
      "version": "8.12.0",
      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.12.0.tgz",
      "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
      "bin": {
        "acorn": "bin/acorn"
      },
@@ -843,7 +559,7 @@
    },
    "node_modules/anymatch": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
      "dependencies": {
        "normalize-path": "^3.0.0",
@@ -886,12 +602,30 @@
        "proxy-from-env": "^1.1.0"
      }
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "node_modules/binary-extensions": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
      "version": "2.3.0",
      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/brace-expansion": {
      "version": "2.0.1",
      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0"
      }
    },
    "node_modules/braces": {
@@ -917,16 +651,21 @@
        "node": ">=0.8"
      }
    },
    "node_modules/chart.js": {
      "version": "4.4.3",
      "resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.4.3.tgz",
      "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
      "dependencies": {
        "@kurkle/color": "^0.3.0"
      },
      "engines": {
        "pnpm": ">=8"
      }
    },
    "node_modules/chokidar": {
      "version": "3.5.3",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
      "funding": [
        {
          "type": "individual",
          "url": "https://paulmillr.com/funding/"
        }
      ],
      "version": "3.6.0",
      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
      "dependencies": {
        "anymatch": "~3.1.2",
        "braces": "~3.0.2",
@@ -938,6 +677,9 @@
      },
      "engines": {
        "node": ">= 8.10.0"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      },
      "optionalDependencies": {
        "fsevents": "~2.3.2"
@@ -961,6 +703,12 @@
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/confbox": {
      "version": "0.1.7",
      "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.7.tgz",
      "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
      "dev": true
    },
    "node_modules/crc-32": {
      "version": "1.2.2",
@@ -1012,6 +760,15 @@
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dom-zindex/-/dom-zindex-1.0.1.tgz",
      "integrity": "sha512-M/MERVDZ8hguvjl6MAlLWSLYLS7PzEyXaTb5gEeJ+SF+e9iUC0sdvlzqe91MMDHBoy+nqw7wKcUOrDSyvMCrRg=="
    },
    "node_modules/echarts": {
      "version": "5.5.0",
      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz",
      "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
      "dependencies": {
        "tslib": "2.3.0",
        "zrender": "5.5.0"
      }
    },
    "node_modules/element-plus": {
      "version": "2.4.0",
@@ -1080,6 +837,18 @@
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
    },
    "node_modules/escape-string-regexp": {
      "version": "5.0.0",
      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
      "dev": true,
      "engines": {
        "node": ">=12"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/estree-walker": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -1090,6 +859,31 @@
      "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz",
      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
      "dev": true
    },
    "node_modules/fast-glob": {
      "version": "3.3.2",
      "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.stat": "^2.0.2",
        "@nodelib/fs.walk": "^1.2.3",
        "glob-parent": "^5.1.2",
        "merge2": "^1.3.0",
        "micromatch": "^4.0.4"
      },
      "engines": {
        "node": ">=8.6.0"
      }
    },
    "node_modules/fastq": {
      "version": "1.17.1",
      "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz",
      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
      "dev": true,
      "dependencies": {
        "reusify": "^1.0.4"
      }
    },
    "node_modules/fill-range": {
      "version": "7.0.1",
@@ -1136,19 +930,6 @@
        "node": ">=0.8"
      }
    },
    "node_modules/fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
      "hasInstallScript": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "node_modules/glob-parent": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -1193,7 +974,7 @@
    },
    "node_modules/is-binary-path": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
      "dependencies": {
        "binary-extensions": "^2.0.0"
@@ -1238,6 +1019,12 @@
        "node": ">=10"
      }
    },
    "node_modules/js-tokens": {
      "version": "9.0.0",
      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.0.tgz",
      "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
      "dev": true
    },
    "node_modules/local-pkg": {
      "version": "0.4.3",
      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
@@ -1270,14 +1057,11 @@
      }
    },
    "node_modules/magic-string": {
      "version": "0.30.5",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
      "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
      "version": "0.30.10",
      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz",
      "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
      "dependencies": {
        "@jridgewell/sourcemap-codec": "^1.4.15"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/magic-string-ast": {
@@ -1295,6 +1079,15 @@
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
    },
    "node_modules/merge2": {
      "version": "1.4.1",
      "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/micromatch": {
      "version": "4.0.5",
@@ -1326,6 +1119,33 @@
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/minimatch": {
      "version": "9.0.4",
      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.4.tgz",
      "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
      "dev": true,
      "dependencies": {
        "brace-expansion": "^2.0.1"
      },
      "engines": {
        "node": ">=16 || 14 >=14.17"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/mlly": {
      "version": "1.7.1",
      "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.1.tgz",
      "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
      "dev": true,
      "dependencies": {
        "acorn": "^8.11.3",
        "pathe": "^1.1.2",
        "pkg-types": "^1.1.1",
        "ufo": "^1.5.3"
      }
    },
    "node_modules/moment": {
@@ -1361,7 +1181,7 @@
    },
    "node_modules/normalize-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
      "engines": {
        "node": ">=0.10.0"
@@ -1373,9 +1193,9 @@
      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
    },
    "node_modules/pathe": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
      "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q=="
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz",
      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="
    },
    "node_modules/picocolors": {
      "version": "1.0.0",
@@ -1451,6 +1271,17 @@
        }
      }
    },
    "node_modules/pkg-types": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.1.1.tgz",
      "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==",
      "dev": true,
      "dependencies": {
        "confbox": "^0.1.7",
        "mlly": "^1.7.0",
        "pathe": "^1.1.2"
      }
    },
    "node_modules/postcss": {
      "version": "8.4.31",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -1483,9 +1314,29 @@
      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    },
    "node_modules/queue-microtask": {
      "version": "1.2.3",
      "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/readdirp": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
      "dependencies": {
        "picomatch": "^2.2.1"
@@ -1499,6 +1350,16 @@
      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
      "dev": true
    },
    "node_modules/reusify": {
      "version": "1.0.4",
      "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
      "dev": true,
      "engines": {
        "iojs": ">=1.0.0",
        "node": ">=0.10.0"
      }
    },
    "node_modules/rollup": {
      "version": "3.29.4",
@@ -1515,6 +1376,35 @@
      "optionalDependencies": {
        "fsevents": "~2.3.2"
      }
    },
    "node_modules/run-parallel": {
      "version": "1.2.0",
      "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "dependencies": {
        "queue-microtask": "^1.2.2"
      }
    },
    "node_modules/scule": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
      "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
      "dev": true
    },
    "node_modules/sortablejs": {
      "version": "1.15.1",
@@ -1538,6 +1428,18 @@
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/strip-literal": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.0.tgz",
      "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
      "dev": true,
      "dependencies": {
        "js-tokens": "^9.0.0"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/sweetalert2": {
@@ -1564,21 +1466,131 @@
        "node": ">=8.0"
      }
    },
    "node_modules/tslib": {
      "version": "2.3.0",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
    },
    "node_modules/ufo": {
      "version": "1.5.3",
      "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.3.tgz",
      "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
      "dev": true
    },
    "node_modules/undici-types": {
      "version": "5.26.5",
      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz",
      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
      "dev": true
    },
    "node_modules/unplugin": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.5.0.tgz",
      "integrity": "sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==",
    "node_modules/unimport": {
      "version": "3.7.2",
      "resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.7.2.tgz",
      "integrity": "sha512-91mxcZTadgXyj3lFWmrGT8GyoRHWuE5fqPOjg5RVtF6vj+OfM5G6WCzXjuYtSgELE5ggB34RY4oiCSEP8I3AHw==",
      "dev": true,
      "dependencies": {
        "acorn": "^8.10.0",
        "chokidar": "^3.5.3",
        "@rollup/pluginutils": "^5.1.0",
        "acorn": "^8.11.3",
        "escape-string-regexp": "^5.0.0",
        "estree-walker": "^3.0.3",
        "fast-glob": "^3.3.2",
        "local-pkg": "^0.5.0",
        "magic-string": "^0.30.10",
        "mlly": "^1.7.0",
        "pathe": "^1.1.2",
        "pkg-types": "^1.1.1",
        "scule": "^1.3.0",
        "strip-literal": "^2.1.0",
        "unplugin": "^1.10.1"
      }
    },
    "node_modules/unimport/node_modules/estree-walker": {
      "version": "3.0.3",
      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
      "dev": true,
      "dependencies": {
        "@types/estree": "^1.0.0"
      }
    },
    "node_modules/unimport/node_modules/local-pkg": {
      "version": "0.5.0",
      "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
      "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
      "dev": true,
      "dependencies": {
        "mlly": "^1.4.2",
        "pkg-types": "^1.0.3"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/unplugin": {
      "version": "1.10.1",
      "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.10.1.tgz",
      "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==",
      "dependencies": {
        "acorn": "^8.11.3",
        "chokidar": "^3.6.0",
        "webpack-sources": "^3.2.3",
        "webpack-virtual-modules": "^0.5.0"
        "webpack-virtual-modules": "^0.6.1"
      },
      "engines": {
        "node": ">=14.0.0"
      }
    },
    "node_modules/unplugin-auto-import": {
      "version": "0.17.6",
      "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.17.6.tgz",
      "integrity": "sha512-dmX0Pex5DzMzVuALkexboOZvh51fL/BD6aoPO7qHoTYGlQp0GRKsREv2KMF1lzYI9SXKQiRxAjwzbQnrFFNydQ==",
      "dev": true,
      "dependencies": {
        "@antfu/utils": "^0.7.8",
        "@rollup/pluginutils": "^5.1.0",
        "fast-glob": "^3.3.2",
        "local-pkg": "^0.5.0",
        "magic-string": "^0.30.10",
        "minimatch": "^9.0.4",
        "unimport": "^3.7.1",
        "unplugin": "^1.10.1"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      },
      "peerDependencies": {
        "@nuxt/kit": "^3.2.2",
        "@vueuse/core": "*"
      },
      "peerDependenciesMeta": {
        "@nuxt/kit": {
          "optional": true
        },
        "@vueuse/core": {
          "optional": true
        }
      }
    },
    "node_modules/unplugin-auto-import/node_modules/local-pkg": {
      "version": "0.5.0",
      "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
      "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
      "dev": true,
      "dependencies": {
        "mlly": "^1.4.2",
        "pkg-types": "^1.0.3"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/vite": {
@@ -1648,6 +1660,22 @@
        "@vue/shared": "3.3.4"
      }
    },
    "node_modules/vue-draggable-plus": {
      "version": "0.5.0",
      "resolved": "https://registry.npmmirror.com/vue-draggable-plus/-/vue-draggable-plus-0.5.0.tgz",
      "integrity": "sha512-A5TT5+M5JceROSjPO9aDZTsrSN1TetEs419czPlboomarSiGIBIxTp2WD7XH53EHMrbO7Qo+leRiHWV/rMlyjA==",
      "dependencies": {
        "@types/sortablejs": "^1.15.8"
      },
      "peerDependencies": {
        "@types/sortablejs": "^1.15.0"
      },
      "peerDependenciesMeta": {
        "@vue/composition-api": {
          "optional": true
        }
      }
    },
    "node_modules/vue-i18n": {
      "version": "9.13.1",
      "resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.13.1.tgz",
@@ -1659,6 +1687,9 @@
      },
      "engines": {
        "node": ">= 16"
      },
      "funding": {
        "url": "https://github.com/sponsors/kazupon"
      },
      "peerDependencies": {
        "vue": "^3.0.0"
@@ -1700,9 +1731,9 @@
      }
    },
    "node_modules/webpack-virtual-modules": {
      "version": "0.5.0",
      "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
      "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="
      "version": "0.6.2",
      "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
      "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="
    },
    "node_modules/wmf": {
      "version": "1.0.2",
@@ -1744,9 +1775,23 @@
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/zrender": {
      "version": "5.5.0",
      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz",
      "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
      "dependencies": {
        "tslib": "2.3.0"
      }
    }
  },
  "dependencies": {
    "@antfu/utils": {
      "version": "0.7.8",
      "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.8.tgz",
      "integrity": "sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==",
      "dev": true
    },
    "@babel/helper-string-parser": {
      "version": "7.22.5",
      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
@@ -1783,157 +1828,10 @@
      "integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
      "requires": {}
    },
    "@esbuild/android-arm": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
      "dev": true,
      "optional": true
    },
    "@esbuild/android-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/android-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/darwin-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/darwin-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/freebsd-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
      "dev": true,
      "optional": true
    },
    "@esbuild/freebsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-arm": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-ia32": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-loong64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-mips64el": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-ppc64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-riscv64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-s390x": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
      "dev": true,
      "optional": true
    },
    "@esbuild/netbsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
      "dev": true,
      "optional": true
    },
    "@esbuild/openbsd-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/sunos-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-arm64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-ia32": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-x64": {
      "version": "0.18.20",
      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
      "dev": true,
      "optional": true
    },
@@ -1987,15 +1885,46 @@
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
    },
    "@kurkle/color": {
      "version": "0.3.2",
      "resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.2.tgz",
      "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
    },
    "@nodelib/fs.scandir": {
      "version": "2.1.5",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
      "dev": true,
      "requires": {
        "@nodelib/fs.stat": "2.0.5",
        "run-parallel": "^1.1.9"
      }
    },
    "@nodelib/fs.stat": {
      "version": "2.0.5",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
      "dev": true
    },
    "@nodelib/fs.walk": {
      "version": "1.2.8",
      "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
      "dev": true,
      "requires": {
        "@nodelib/fs.scandir": "2.1.5",
        "fastq": "^1.6.0"
      }
    },
    "@popperjs/core": {
      "version": "npm:@sxzz/popperjs-es@2.11.7",
      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
    },
    "@rollup/pluginutils": {
      "version": "5.0.5",
      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
      "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
      "version": "5.1.0",
      "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
      "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
      "requires": {
        "@types/estree": "^1.0.0",
        "estree-walker": "^2.0.2",
@@ -2039,10 +1968,9 @@
      }
    },
    "@types/sortablejs": {
      "version": "1.15.7",
      "resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.7.tgz",
      "integrity": "sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==",
      "dev": true
      "version": "1.15.8",
      "resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.8.tgz",
      "integrity": "sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg=="
    },
    "@types/web-bluetooth": {
      "version": "0.0.16",
@@ -2050,9 +1978,9 @@
      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
    },
    "@vitejs/plugin-vue": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.4.0.tgz",
      "integrity": "sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==",
      "version": "4.6.2",
      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
      "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
      "dev": true,
      "requires": {}
    },
@@ -2227,9 +2155,9 @@
      }
    },
    "acorn": {
      "version": "8.10.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw=="
      "version": "8.12.0",
      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.12.0.tgz",
      "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw=="
    },
    "adler-32": {
      "version": "1.3.1",
@@ -2238,7 +2166,7 @@
    },
    "anymatch": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
      "requires": {
        "normalize-path": "^3.0.0",
@@ -2275,10 +2203,25 @@
        "proxy-from-env": "^1.1.0"
      }
    },
    "balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "binary-extensions": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
      "version": "2.3.0",
      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
    },
    "brace-expansion": {
      "version": "2.0.1",
      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0"
      }
    },
    "braces": {
      "version": "3.0.2",
@@ -2297,10 +2240,18 @@
        "crc-32": "~1.2.0"
      }
    },
    "chart.js": {
      "version": "4.4.3",
      "resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.4.3.tgz",
      "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
      "requires": {
        "@kurkle/color": "^0.3.0"
      }
    },
    "chokidar": {
      "version": "3.5.3",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
      "version": "3.6.0",
      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
      "requires": {
        "anymatch": "~3.1.2",
        "braces": "~3.0.2",
@@ -2324,6 +2275,12 @@
      "requires": {
        "delayed-stream": "~1.0.0"
      }
    },
    "confbox": {
      "version": "0.1.7",
      "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.7.tgz",
      "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
      "dev": true
    },
    "crc-32": {
      "version": "1.2.2",
@@ -2358,6 +2315,15 @@
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dom-zindex/-/dom-zindex-1.0.1.tgz",
      "integrity": "sha512-M/MERVDZ8hguvjl6MAlLWSLYLS7PzEyXaTb5gEeJ+SF+e9iUC0sdvlzqe91MMDHBoy+nqw7wKcUOrDSyvMCrRg=="
    },
    "echarts": {
      "version": "5.5.0",
      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz",
      "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
      "requires": {
        "tslib": "2.3.0",
        "zrender": "5.5.0"
      }
    },
    "element-plus": {
      "version": "2.4.0",
@@ -2416,6 +2382,12 @@
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
    },
    "escape-string-regexp": {
      "version": "5.0.0",
      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
      "dev": true
    },
    "estree-walker": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -2426,6 +2398,28 @@
      "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz",
      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
      "dev": true
    },
    "fast-glob": {
      "version": "3.3.2",
      "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
      "dev": true,
      "requires": {
        "@nodelib/fs.stat": "^2.0.2",
        "@nodelib/fs.walk": "^1.2.3",
        "glob-parent": "^5.1.2",
        "merge2": "^1.3.0",
        "micromatch": "^4.0.4"
      }
    },
    "fastq": {
      "version": "1.17.1",
      "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz",
      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
      "dev": true,
      "requires": {
        "reusify": "^1.0.4"
      }
    },
    "fill-range": {
      "version": "7.0.1",
@@ -2454,12 +2448,6 @@
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz",
      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
    },
    "fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
      "optional": true
    },
    "glob-parent": {
      "version": "5.1.2",
@@ -2496,7 +2484,7 @@
    },
    "is-binary-path": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
      "requires": {
        "binary-extensions": "^2.0.0"
@@ -2526,6 +2514,12 @@
      "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
      "dev": true
    },
    "js-tokens": {
      "version": "9.0.0",
      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.0.tgz",
      "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
      "dev": true
    },
    "local-pkg": {
      "version": "0.4.3",
      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
@@ -2548,9 +2542,9 @@
      "requires": {}
    },
    "magic-string": {
      "version": "0.30.5",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
      "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
      "version": "0.30.10",
      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz",
      "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
      "requires": {
        "@jridgewell/sourcemap-codec": "^1.4.15"
      }
@@ -2567,6 +2561,12 @@
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
    },
    "merge2": {
      "version": "1.4.1",
      "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
      "dev": true
    },
    "micromatch": {
      "version": "4.0.5",
@@ -2591,6 +2591,27 @@
        "mime-db": "1.52.0"
      }
    },
    "minimatch": {
      "version": "9.0.4",
      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.4.tgz",
      "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
      "dev": true,
      "requires": {
        "brace-expansion": "^2.0.1"
      }
    },
    "mlly": {
      "version": "1.7.1",
      "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.1.tgz",
      "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
      "dev": true,
      "requires": {
        "acorn": "^8.11.3",
        "pathe": "^1.1.2",
        "pkg-types": "^1.1.1",
        "ufo": "^1.5.3"
      }
    },
    "moment": {
      "version": "2.30.1",
      "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
@@ -2609,7 +2630,7 @@
    },
    "normalize-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
    },
    "normalize-wheel-es": {
@@ -2618,9 +2639,9 @@
      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
    },
    "pathe": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
      "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q=="
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz",
      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="
    },
    "picocolors": {
      "version": "1.0.0",
@@ -2655,6 +2676,17 @@
      "integrity": "sha512-tZbNGf2vjAQcIm7alK40sE51Qu/m9oWr+rEgNm/2AWr1huFxj72CjvpQcIQzMknDBJEkQznCLAGtJTIcLKrKdw==",
      "requires": {}
    },
    "pkg-types": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.1.1.tgz",
      "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==",
      "dev": true,
      "requires": {
        "confbox": "^0.1.7",
        "mlly": "^1.7.0",
        "pathe": "^1.1.2"
      }
    },
    "postcss": {
      "version": "8.4.31",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -2670,9 +2702,15 @@
      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    },
    "queue-microtask": {
      "version": "1.2.3",
      "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
      "dev": true
    },
    "readdirp": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
      "requires": {
        "picomatch": "^2.2.1"
@@ -2684,6 +2722,12 @@
      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
      "dev": true
    },
    "reusify": {
      "version": "1.0.4",
      "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
      "dev": true
    },
    "rollup": {
      "version": "3.29.4",
      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
@@ -2692,6 +2736,21 @@
      "requires": {
        "fsevents": "~2.3.2"
      }
    },
    "run-parallel": {
      "version": "1.2.0",
      "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
      "dev": true,
      "requires": {
        "queue-microtask": "^1.2.2"
      }
    },
    "scule": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
      "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
      "dev": true
    },
    "sortablejs": {
      "version": "1.15.1",
@@ -2709,6 +2768,15 @@
      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
      "requires": {
        "frac": "~1.1.2"
      }
    },
    "strip-literal": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.0.tgz",
      "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
      "dev": true,
      "requires": {
        "js-tokens": "^9.0.0"
      }
    },
    "sweetalert2": {
@@ -2729,21 +2797,102 @@
        "is-number": "^7.0.0"
      }
    },
    "tslib": {
      "version": "2.3.0",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
    },
    "ufo": {
      "version": "1.5.3",
      "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.3.tgz",
      "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
      "dev": true
    },
    "undici-types": {
      "version": "5.26.5",
      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz",
      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
      "dev": true
    },
    "unplugin": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.5.0.tgz",
      "integrity": "sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==",
    "unimport": {
      "version": "3.7.2",
      "resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.7.2.tgz",
      "integrity": "sha512-91mxcZTadgXyj3lFWmrGT8GyoRHWuE5fqPOjg5RVtF6vj+OfM5G6WCzXjuYtSgELE5ggB34RY4oiCSEP8I3AHw==",
      "dev": true,
      "requires": {
        "acorn": "^8.10.0",
        "chokidar": "^3.5.3",
        "@rollup/pluginutils": "^5.1.0",
        "acorn": "^8.11.3",
        "escape-string-regexp": "^5.0.0",
        "estree-walker": "^3.0.3",
        "fast-glob": "^3.3.2",
        "local-pkg": "^0.5.0",
        "magic-string": "^0.30.10",
        "mlly": "^1.7.0",
        "pathe": "^1.1.2",
        "pkg-types": "^1.1.1",
        "scule": "^1.3.0",
        "strip-literal": "^2.1.0",
        "unplugin": "^1.10.1"
      },
      "dependencies": {
        "estree-walker": {
          "version": "3.0.3",
          "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
          "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
          "dev": true,
          "requires": {
            "@types/estree": "^1.0.0"
          }
        },
        "local-pkg": {
          "version": "0.5.0",
          "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
          "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
          "dev": true,
          "requires": {
            "mlly": "^1.4.2",
            "pkg-types": "^1.0.3"
          }
        }
      }
    },
    "unplugin": {
      "version": "1.10.1",
      "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.10.1.tgz",
      "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==",
      "requires": {
        "acorn": "^8.11.3",
        "chokidar": "^3.6.0",
        "webpack-sources": "^3.2.3",
        "webpack-virtual-modules": "^0.5.0"
        "webpack-virtual-modules": "^0.6.1"
      }
    },
    "unplugin-auto-import": {
      "version": "0.17.6",
      "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.17.6.tgz",
      "integrity": "sha512-dmX0Pex5DzMzVuALkexboOZvh51fL/BD6aoPO7qHoTYGlQp0GRKsREv2KMF1lzYI9SXKQiRxAjwzbQnrFFNydQ==",
      "dev": true,
      "requires": {
        "@antfu/utils": "^0.7.8",
        "@rollup/pluginutils": "^5.1.0",
        "fast-glob": "^3.3.2",
        "local-pkg": "^0.5.0",
        "magic-string": "^0.30.10",
        "minimatch": "^9.0.4",
        "unimport": "^3.7.1",
        "unplugin": "^1.10.1"
      },
      "dependencies": {
        "local-pkg": {
          "version": "0.5.0",
          "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.0.tgz",
          "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
          "dev": true,
          "requires": {
            "mlly": "^1.4.2",
            "pkg-types": "^1.0.3"
          }
        }
      }
    },
    "vite": {
@@ -2768,6 +2917,14 @@
        "@vue/runtime-dom": "3.3.4",
        "@vue/server-renderer": "3.3.4",
        "@vue/shared": "3.3.4"
      }
    },
    "vue-draggable-plus": {
      "version": "0.5.0",
      "resolved": "https://registry.npmmirror.com/vue-draggable-plus/-/vue-draggable-plus-0.5.0.tgz",
      "integrity": "sha512-A5TT5+M5JceROSjPO9aDZTsrSN1TetEs419czPlboomarSiGIBIxTp2WD7XH53EHMrbO7Qo+leRiHWV/rMlyjA==",
      "requires": {
        "@types/sortablejs": "^1.15.8"
      }
    },
    "vue-i18n": {
@@ -2803,9 +2960,9 @@
      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="
    },
    "webpack-virtual-modules": {
      "version": "0.5.0",
      "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
      "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="
      "version": "0.6.2",
      "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
      "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="
    },
    "wmf": {
      "version": "1.0.2",
@@ -2835,6 +2992,14 @@
        "wmf": "~1.0.1",
        "word": "~0.3.0"
      }
    },
    "zrender": {
      "version": "5.5.0",
      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz",
      "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
      "requires": {
        "tslib": "2.3.0"
      }
    }
  }
}
UI-Project/package.json
@@ -11,6 +11,8 @@
    "@element-plus/icons-vue": "^2.1.0",
    "@vue-macros/reactivity-transform": "^0.3.23",
    "axios": "^1.6.8",
    "chart.js": "^4.4.3",
    "echarts": "^5.5.0",
    "element-plus": "^2.4.0",
    "moment": "^2.30.1",
    "pinia": "^2.1.6",
@@ -18,7 +20,8 @@
    "sortablejs": "^1.15.1",
    "sweetalert2": "^11.10.7",
    "vue": "^3.3.4",
    "vue-i18n": "^9.13.1",
    "vue-draggable-plus": "^0.5.0",
    "vue-i18n": "^9.10.1",
    "vue-router": "^4.2.4",
    "vxe-table": "^4.5.15",
    "xe-utils": "^3.5.14",
@@ -26,8 +29,9 @@
  },
  "devDependencies": {
    "@types/sortablejs": "^1.15.7",
    "@vitejs/plugin-vue": "^4.3.4",
    "@vitejs/plugin-vue": "^4.6.2",
    "http-proxy-middleware": "^3.0.0",
    "unplugin-auto-import": "^0.17.6",
    "vite": "^4.4.9"
  }
}
UI-Project/src/lang/LanguageMixin.js
File was deleted
UI-Project/src/lang/en.js
New file
@@ -0,0 +1,302 @@
export  default {
    "northglassMESsystem": 'Система "NorthGlass MES"' ,
      login:{
          userErr:'Введите номер счета.',
          pwErr:'Введите пароль.',
          user:'Аккаунт',
          password:'Код',
          login:'Залогин',
          loginSuccessful:'Вход в систему выполнен успешно!',
          register:'Зарегистрирова',
          namea:'Имя не может быть пустым',
          len:'Длина не должна превышать 16',
          passnull:'Пароль не может быть пустым',
          leng:'Длина пароля не должна быть меньше 6 или больше 16.',
          spwn:'Пароль подтверждения не может быть пустым',
          depass:'Два разных пароля.',
      },
      register:{
          registerSuccessful:'Регистрация успешно',
          newuserregister:'Новый реестр пользователей',
          name:'Имя:',
          inputname:'Введите имя',
          password:'Код:',
          pwErr:'Введите пароль.',
          passwordation:'Подтвердите пароль:',
          pwErration:'Пожалуйста, подтвертите пароль',
          registration:'Подтверждение о регистрации',
          false:'Отмена',
      },
      main:{
          connectErr:'Необычное подключение к серверу, попробуйте позже',
          titleFirst:"Добро пожаловать ",
          titleLast:' в систему NorthGlass MES!',
          quit:"Выход",
      },
      basicData:{
          deletemessage:'Удалить эту информацию или нет?',
          laserprinting:'Машина лазерной маркировки готова:',
          cuttingmachine:'Машина для резки готова:',
          machine:'Состояние станок загрузки в режиме онлайн:',
          machineaa:'Ручное состояние станок загрузки:',
          selectproject:"Выберите проект",
          startloading:'Начало загрузки',
          stop:'Пауза',
          yes:'подтверд',
          change:'переключа',
          projectnumber:'Номер проекта',
          glasswidth:'Ширина стекла',
          glassheight:'Высота стекла',
          coatingtypes:'Типы покрытий',
          coatingtypesa:'Типы покрытий:',
          quantity:'Количество',
          quantitya:'Количество:',
          thickness:'Толщина',
          thicknessa:'Толщина:',
          startstatus:'Статус начала операции',
          pass:'Через',
          waiting:'Ждем.',
          up:'Загрузка',
          finish:'Завершено',
          project:'инженерия',
          plselectproject:'Пожалуйста, выберите проект.',
          confirm:'подтверд',
          cancel:'Отмена',
          startfilm:'Начинать или нет?',
          whetherpause:'Пауза или нет?',
          station:'Рабочее место',
          width:'Ширина',
          widtha:'Ширина:',
          height:'Высота',
          heighta:'Высота:',
          operate:'Операция',
          add:'Добавля',
          delete:'Удал',
          addglass:'Добавить стекло',
          selectwidth:'Выбирите ширину',
          selectheight:'Выбирите высоту',
          selectcoatingtypes:'Выберите типы покрытий',
          selectthickness:'Выберите толщину',
          selectquantity:'Введите кольчество.',
          pause:'Вторая и четвертая строки должны быть выше 2700 для сохранения!',
          pausea:'Пожалуйста, убедитесь, что маркировочная и режущая машины готовы!',
          infonull:'Номер проекта не может быть пустым!',
          updatanull:'Проект не сохранились на листе загрузки!',
          glassnull:'Ошибка при обновлении стекла',
      },
      sorter:{
          gridnumber:'Ячеек сеткла',
          glassnumber:'Номер стакла',
          width:'Ширина',
          height:'Высота',
          startstatus:'Статус начала операции',
          disable:'Отключ',
          start:'Начало',
          deficiencieste:'Недостатки в отчетности',
          operate:'Операция',
          prompt:'Подсказк',
          information:'Следует ли сообщать недостающую информацию?',
          yes:'Да',
          cancel:'Отмена',
      },
      order:{
          dilapidation:'Повреждение',
          Takeaway:'Взять вручную',
      },
      searchOrder:{
        cageinformation:'Информация буфера',
        productionqueue:'Производственная очередь',
        outputglassID:'Выходное стекло ID',
        startposition:'Занять позиции',
        targetlocation:'Позиция цели',
        trips:'№ поезда',
        number:'Серийн номер',
        taskstatus:'Состояние задачи',
        filmenter:'Ожидание стеклянной вход',
        infilm:'В настоящее время',
        endtask:'Задача на конец',
        completetask:'Выполнение задания',
        intoglassid:'Входной стеклянный ID',
        line:'Линия',
        Usage:'Скорость использования',
        free:'Бесплатно (ячеек)',
        addcage:'Добавить информацию о буфере',
        glassIDa:'Стеклянный ID:',
        glassID:'Стеклянный ID',
        inglassID:'Введите стекло ID',
        pieceingrid:'Порядок расположения маленьких стеклянных пластин в клетке',
        pieceingrida:'Порядок расположения маленьких стеклянных пластин в клетке:',
        inpieceingrid:'Введите порядок расположения стеклянных листов в ячееке',
        cardnumber:'Номер карточки процесса',
        cardnumbera:'Номер карточки процесса:',
        incardnumber:'Введите номер процесса .',
        typeglass:'Тип стекла',
        typeglassa:'Тип стекла:',
        intypeglass:'Введите тип стекла',
        coatingtypes:'Типы покрытий',
        width:'Ширина',
        widtha:'Ширина:',
        inwidth:'Введите ширину',
        height:'Высота',
        heighta:'Высота:',
        inheight:'Введите высоту',
        thickness:'Толщина',
        thicknessa:'Толщина:',
        inthickness:'Введите толщину.',
        layoutID:'Чертеж ID загрузки печи для закалки',
        layoutIDa:'Чертеж ID загрузки печи для закалки:',
        inlayoutID:'Введите чертеж закалки ID',
        picturesequence:'Чертеж серийн номер загрузки печи для закалки',
        picturesequencea:'Чертеж серийн номер загрузки печи для закалки:',
        inpicturesequence:'Введите порядок чертежи закалки стекла.',
        startstatus:'Статус начала операции',
        startstatusa:'Статус начала операции:',
        instartstatus:'Введите состояние активации',
        glassgaps:'Стеклянный зазор',
        glassgapsa:'Стеклянный зазор:',
        inglassgaps:'Введите стекло зазор',
        sure:'подтверд',
        cancel:'Отмена',
        glassID:'Стеклянный ID',
        operate:'Операция',
        breakage:'Повреждение',
        delete:'Удал',
        outfilm:'Выпуск стекла',
        cagetableID:'ID буферной таблицы',
        cagenumber:'Буфер номера',
        gridnumber:'Ячеек сеткла',
        enable:'Начало',
        disable:'Отключ',
        remainingwidth:'Остаточная ширина',
        add:'Добавля',
        sheetID:'Закалка маленький стеклянный ID таблицы информации',
        processcards:'Карточка процесса',
        processcardtype:'Тип стекла карточки процесса',
        acceptshorizontal:'Умеренное принятие горизонтали',
        xcoordinates:'X-координаты',
        ycoordinates:'Y-координаты',
        rotationangle:'Угол вращения (против часовой стрелки)',
        state:'Состояние',
        takeout:'Взять',
        deletemessage:'Удалить эту информацию или нет?',
        prompt:'Подсказк',
        yes:'Да',
        accept:'Принять',
        noaccept:'Не принимать',
        filmcomplete:'Стекло готово',
        waiting:'Ждем.',
    },
    workOrder:{
        glassID:'Стеклянный ID',
        height:'Высота',
        width:'Ширина',
        thickness:'Толщина',
        coatingtypes:'Типы покрытий',
        productionsequence:'Последовательность производства',
        cardnumber:'Номер карточки процесса',
        operate:'Операция',
        messagedamaged:'Повреждено ли сообщение?',
        prompt:'Подсказк',
        yes:'Да',
        cancel:'Отмена',
        takemessage:'Следует ли удалять сообщение?',
        breakage:'Повреждение',
        takeout:'Взять',
    },
    processCard:{
        intofurnace:'В печь',
        beforefurnace:'До печки.',
        outfurnace:'Окончено стекло из печи для закалки',
    },
    reportWork:{
        lowerbit:'Станция разгрузки',
        shelfnumber:'Номер стойки регистрации',
        cardnumber:'Номер карточки процесса',
        totalquantity:'Общее количество',
        beendropped:'Количество стекла разгрузки',
        state:'Состояние',
        devicenumber:'Номер оборудования.',
        startstatus:'Статус начала операции',
        enable:'Начало',
        unenable:'Не начат',
        operate:'Операция',
        bindingshelves:'Назначенная стеллажка',
        clear:'Чисто.',
        workstation:'Станция номер',
        shelfnumber:'Номер стойки регистрации:',
        cardnumbera:'Номер карточки процесса:',
        incardnumber:'Пожалуйста, выберите номер программы',
        clearglass:'Очистить стекло с полки',
        sure:'подтверд',
        cancel:'Отмена',
        glassinformation:'Информация стекла',
        glassID:'Стеклянный ID',
        coatingtypes:'Типы покрытий',
        thickness:'Толщина',
        width:'Ширина',
        height:'Высота',
    },
    productStock:{
        addusers:'Добавьте пользователей.',
        username:'Имя пользователя.',
        usernamea:'Имя пользователя.:',
        inusername:'Введите имя пользователя',
        role:'Роль',
        rolea:'Роль:',
        inrole:'Выберите роль',
        test:'Тест',
        admin:'Администратор.',
        operate:'Операция',
        resetpassword:'Сбросить пароль',
        exit:'Редактор',
        delete:'Удал',
        prompt:'Подсказк',
        repassword:'Перезагрузка пользовательского пароля или нет?',
        yes:'Да',
        cancel:'Отмена',
        reusername:'Изменение пользователя',
        addusername:'Добавьте пользователей.',
        password:'Код:',
        sure:'подтверд',
        inpassword:'Введите пароль.',
        deusername:'Удаление пользователя или нет?',
    },
    customer:{
        addmenu:'Добавьте меню.',
        firstmenu:'Таблица меню первой степени',
        link:'Ссылк',
        linka:'Ссылк:',
        inlink:'Введите ссылку',
        sort:'Сортировк',
        sorta:'Сортировк:',
        insort:'Введите сортировку',
        operate:'Операция',
        exit:'Редактор',
        inmenu:'Введите меню',
        delete:'Удал',
        semenu:'Таблица меню второй степени',
        menu:'Меню.:',
        sure:'подтверд',
        cancel:'Отмена',
        exmene:'Изменение меню.',
        yes:'Да',
        demenu:'Удалить меню или нет?',
        prompt:'Подсказк',
    },
    delivery:{
        addrole:'Добавьте роли.',
        editrole:'Изменение роли.',
        role :'Роль',
        rolea :'Роль:',
        inrole :'Введите роли.',
        operate :'Операция',
        edit :'Редактор',
        delete :'Удал',
        sure :'подтверд',
        cancel :'Отмена',
        yes:'Да',
        derole :'Удалить персонаж или нет?',
        prompt:'Подсказк',
    },
  }
UI-Project/src/lang/i18n.js
File was deleted
UI-Project/src/lang/index.js
New file
@@ -0,0 +1,18 @@
import { createI18n}  from 'vue-i18n'
import zh from "./zh"
import en from "./en"
let messages = {
    zh:zh,
    en: en
}
const i18n = createI18n({
    locale: localStorage.getItem('lang') || 'zh', // 设置当前语言类型
    legacy: false, // 如果要支持compositionAPI,此项必须设置为false;
    globalInjection: true, // 全局注册$t方法
    messages
})
export default i18n
UI-Project/src/lang/locales/en-US.json
File was deleted
UI-Project/src/lang/locales/zh-CN.json
File was deleted
UI-Project/src/lang/zh.js
New file
@@ -0,0 +1,371 @@
export  default {
  "northglassMESsystem": "北玻MES系统",
    login:{
        userErr:'请输入账号',
        pwErr:'请输入密码',
        user:'账号',
        password:'密码',
        login:'登录',
        loginSuccessful:'登录成功!',
        register:'注册',
        namea:'姓名不能为空',
        len:'长度不能超过16',
        passnull:'密码不能为空',
        leng:'密码长度不能低于6或超过16',
        spwn:'确认密码不能为空',
        depass:'两次密码不相同',
    },
    register:{
        registerSuccessful:'注册成功',
        newuserregister:'注册新用户',
        name:'姓名:',
        inputname:'请输入姓名',
        password:'密码:',
        pwErr:'请输入密码',
        passwordation:'确认密码:',
        pwErration:'请确认密码',
        registration:'确认注册',
        false:'取消',
    },
    main:{
        connectErr:'服务器连接异常,请稍后再试',
        titleFirst:"欢迎 ",
        titleLast:' 使用北玻MES系统!',
        quit:"退出",
    },
    basicData:{
        laserprinting:'打标机就绪状态:',
        cuttingmachine:'切割机就绪状态:',
        machine:'上片机联机状态:',
        machineaa:'上片机手动状态:',
        selectproject:"选择工程",
        startloading:'开始上片',
        stop:'暂停',
        yes:'确认',
        change:'切换',
        projectnumber:'工程号',
        glasswidth:'原片宽',
        glassheight:'原片高',
        coatingtypes:'膜系',
        coatingtypesa:'膜系:',
        quantity:'数量',
        quantitya:'数量:',
        thickness:'厚度',
        thicknessa:'厚度:',
        startstatus:'启用状态',
        pass:'通过',
        waiting:'等待中',
        up:'上片中',
        finish:'已完成',
        project:'工程',
        plselectproject:'请选择工程',
        confirm:'确认',
        cancel:'取消',
        startfilm:'是否开始上片?',
        whetherpause:'是否暂停?',
        station:'工位',
        width:'宽',
        widtha:'宽:',
        height:'高',
        heighta:'高:',
        operate:'操作',
        add:'添加',
        delete:'删除',
        addglass:'添加原片',
        selectwidth:'请选择宽',
        selectheight:'请选择高',
        selectcoatingtypes:'请选择膜系',
        selectthickness:'请选择厚度',
        selectquantity:'请输入数量',
        pause:'第二行和第四行的高必须大于2700才能保存!',
        pausea:'请确认打标机和切割机的就绪状态!',
        infonull:'工程号不能为空!',
        updatanull:'该工程未保存到上片表!',
        glassnull:'更新玻璃状态时发生错误',
        deletemessage:'是否删除该条信息?',
    },
    sorter:{
        gridnumber:'栅格号',
        glassnumber:'玻璃编号',
        width:'宽',
        height:'高',
        startstatus:'启用状态',
        disable:'禁用',
        start:'启用',
        deficiencieste:'报缺',
        updown:'人工下片',
        operate:'操作',
        prompt:'提示',
        information:'是否报缺该条信息?',
        infor:'是否人工下片该条信息?',
        yes:'是',
        cancel:'取消',
    },
    order:{
        dilapidation:'破损',
        Takeaway:'人工拿走',
    },
    searchOrder:{
        cageinformation:'理片笼信息',
        productionqueue:'出片队列',
        outputglassID:'出片玻璃ID',
        startposition:'起始位置',
        targetlocation:'目标位置',
        trips:'车次',
        number:'序号',
        taskstatus:'任务状态',
        filmenter:'等待进片',
        infilm:'进行中',
        endtask:'结束任务',
        completetask:'完成任务',
        intoglassid:'进片玻璃ID',
        line:'线路',
        Usage:'使用率',
        free:'空闲(格子数)',
        addcage:'添加理片笼信息',
        glassIDa:'玻璃ID:',
        glassID:'玻璃ID',
        inglassID:'请输入玻璃ID',
        pieceingrid:'小片在格内的顺序',
        pieceingrida:'小片在格内的顺序:',
        inpieceingrid:'请输入小片在格内的顺序',
        cardnumber:'流程卡号',
        cardnumbera:'流程卡号:',
        incardnumber:'请输入流程卡号',
        typeglass:'玻璃类型',
        typeglassa:'玻璃类型:',
        intypeglass:'请输入玻璃类型',
        width:'宽',
        widtha:'宽:',
        inwidth:'请输入宽',
        height:'高',
        heighta:'高:',
        inheight:'请输入高',
        coatingtypes:'膜系',
        thickness:'厚度',
        thicknessa:'厚度:',
        inthickness:'请输入厚度',
        layoutID:'钢化版图ID',
        layoutIDa:'钢化版图ID:',
        inlayoutID:'请输入钢化版图ID',
        picturesequence:'钢化版图片序',
        picturesequencea:'钢化版图片序:',
        inpicturesequence:'请输入钢化版图片序',
        startstatus:'启用状态',
        startstatusa:'启用状态:',
        instartstatus:'请输入启用状态',
        glassgaps:'玻璃间隙',
        glassgapsa:'玻璃间隙:',
        inglassgaps:'请输入玻璃间隙',
        sure:'确认',
        cancel:'取消',
        glassID:'玻璃ID',
        operate:'操作',
        breakage:'破损',
        delete:'删除',
        outfilm:'出片',
        cagetableID:'大理片笼表ID',
        cagenumber:'理片笼号',
        gridnumber:'栅格号',
        gridnumbera:'栅格号:',
        grid:'请输入栅格号',
        enable:'启用',
        disable:'禁用',
        remainingwidth:'剩余宽度',
        add:'添加',
        sheetID:'钢化小片信息表ID',
        processcards:'流程卡',
        processcardtype:'流程卡玻璃类型',
        acceptshorizontal:'钢化是否接受横放',
        xcoordinates:'x坐标',
        ycoordinates:'y坐标',
        rotationangle:'旋转角度(逆时针)',
        state:'状态',
        takeout:'拿走',
        deletemessage:'是否删除该条信息?',
        prompt:'提示',
        yes:'是',
        accept:'接受',
        noaccept:'不接受',
        filmcomplete:'出片完成',
        waiting:'等待中',
        broke:'是否破损该条信息?',
        brokeb:'是否拿走该条信息?',
        outfil:'是否出片该条信息?',
        inputid:'请输入玻璃ID',
        search:'搜索',
        tabid:'大理片笼详情表id',
        tid:'设备id',
        tida:'设备id:',
        fin:'是否完成任务?',
        sureadd:'确认添加',
        sureadda:'是否确认添加?',
        zailong:'在笼中',
        rengongxp:'人工下片',
        up:'上一页',
        down:'下一页',
        now:'当前页显示',
        tit:'条数据',
    },
    workOrder:{
        glassID:'玻璃ID',
        height:'高',
        width:'宽',
        thickness:'厚度',
        coatingtypes:'膜系',
        productionsequence:'出片顺序',
        cardnumber:'流程卡号',
        operate:'操作',
        messagedamaged:'是否破损该条信息?',
        prompt:'提示',
        yes:'是',
        cancel:'取消',
        takemessage:'是否拿走该条信息?',
        breakage:'破损',
        takeout:'拿走',
    },
    processCard:{
        intofurnace:'进炉中',
        beforefurnace:'进炉前',
        outfurnace:'已出炉玻璃',
    },
    reportWork:{
        lowerbit:'下片位',
        shelfnumber:'架号',
        cardnumber:'流程卡号',
        totalquantity:'总数量',
        beendropped:'已落架数量',
        state:'状态',
        devicenumber:'设备号',
        startstatus:'启用状态',
        enable:'启用',
        unenable:'未启用',
        operate:'操作',
        bindingshelves:'绑定架子',
        clear:'清空',
        workstation:'号工位',
        shelfnumbera:'架号:',
        cardnumbera:'流程卡号:',
        incardnumber:'请选择流程卡号',
        clearglass:'清除架子玻璃',
        sure:'确认',
        cancel:'取消',
        glassinformation:'玻璃信息',
        glassID:'玻璃ID',
        coatingtypes:'膜系',
        thickness:'厚度',
        width:'宽度',
        height:'高度',
    },
    productStock:{
        addusers:'添加用户',
        username:'用户名',
        usernamea:'用户名:',
        inusername:'请输入用户名',
        role:'角色',
        rolea:'角色:',
        inrole:'请选择角色',
        test:'测试',
        admin:'管理员',
        operate:'操作',
        resetpassword:'重置密码',
        exit:'编辑',
        delete:'删除',
        prompt:'提示',
        repassword:'是否重置用户密码?',
        yes:'是',
        cancel:'取消',
        reusername:'修改用户',
        addusername:'添加用户',
        password:'密码:',
        sure:'确认',
        inpassword:'请输入密码',
        deusername:'是否删除该用户?',
    },
    customer:{
        addmenua:'添加二级菜单',
        addmenu:'添加一级菜单',
        firstmenu:'一级菜单栏',
        firstmenuname:'一级菜单名称:',
        link:'链接',
        inlink:'请输入链接',
        linka:'链接:',
        sort:'排序',
        insort:'请输入排序',
        sorta:'排序:',
        operate:'操作',
        exit:'编辑',
        delete:'删除',
        semenu:'二级菜单栏',
        semenuname:'二级菜单名称:',
        menu:'菜单栏:',
        inmenu:'请输入菜单名称',
        sure:'确认',
        cancel:'取消',
        exmene:'修改一级菜单',
        exmenea:'修改二级菜单',
        yes:'是',
        demenu:'是否删除该菜单?',
        prompt:'提示',
    },
    delivery:{
        addrole:'添加角色',
        editrole:'修改角色',
        role :'角色',
        rolea :'角色:',
        inrole :'请输入角色',
        operate :'操作',
        edit :'编辑',
        delete :'删除',
        yes:'是',
        sure :'确认',
        cancel :'取消',
        derole :'是否删除该角色',
        prompt:'提示',
        choice:'菜单权限:',
        inchoice:'请选择菜单权限',
    },
    replenish:{
        patchManagement:'补片管理',
    },
    rework:{
        reworkManagement:'返工管理',
        addRework:"返工新增 ",
    },
    role:{
        id:'ID',
        characterHomepage:'角色首页',
    },
    user:{
        userId:'用户ID',
        userHomepage:'用户首页',
    },
    orderBasicData:{
        order:'订单',
        orderType:'订单类型',
    },
    machine:{
        basicId:'设备编号',
        basicName:'设备名称',
        basicCategory:'所在工序',
        tempering:'钢化',
    },
    report:{
        productionReport:'生产报表',
        workInProgressReport:'在制品报表',
    },
    productionBasicData:{
        basicDataQuery :'基础数据查询',
    },
    mainIngredient:{
        materialInformation :'物料资料',
    },
    mainIngredientStock:{
        materialName :'物料名称',
        createTime :'返库日期',
    },
}
UI-Project/src/layout/MainErpView.vue
@@ -1,14 +1,17 @@
<script setup>
import {useRouter} from 'vue-router'
import useUserInfoStore from '@/stores/userInfo'
import userInfo from '@/stores/userInfo'
import request from '@/utils/request'
import {ElMessage} from 'element-plus'
import {ref, watch} from 'vue'
import {ref, watch, onMounted } from 'vue'
import deepClone from '@/utils/deepClone'
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const store = userInfo()
// const { $i18n } = useI18n(); // 获取 i18n 实例
const router = useRouter()
const userStore = useUserInfoStore()
const user = userStore.user.userName
@@ -19,27 +22,32 @@
// let userInfo = userInfoStr.user.token;  
let token = userInfo; // 提取 token  
// 退出登录方法  
const quit = async () => {
  try  {
    const response = await request.get('/loadGlass/sys/user/logout', {
        token: token,
        user: null,
    })
    if (response.code === 200) {
        // 登出成功,清除本地存储的 userInfo
        localStorage.removeItem('userInfo');
        // 可以在这里重置应用状态,如导航到登录页等
        console.log('登出成功');
      } else {
        // 处理错误情况
        console.error('登出失败', response);
      }
function quit() {
  // removeToken()
  router.push('/login')
}
catch (error) {
    // 处理错误
    console.error(error);
  }
}
// const quit = async () => {
//   try  {
//     const response = await request.get('/loadGlass/sys/user/logout', {
//         token: token,
//         user: null,
//     })
//     if (response.code === 200) {
//         // 登出成功,清除本地存储的 userInfo
//         localStorage.removeItem('userInfo');
//         // 可以在这里重置应用状态,如导航到登录页等
//         console.log('登出成功');
//       } else {
//         // 处理错误情况
//         console.error('登出失败', response);
//       }
// }
// catch (error) {
//     // 处理错误
//     console.error(error);
//   }
// }
// store.createWebSocket();
// function quit() {
//   userStore.$patch({
@@ -57,26 +65,79 @@
//    });
// }
  function replaceChineseWithEnglish(menuData) {
      // 定义中英文对照关系对象
       const translation  = {
          '上片机': 'Стол загрузки',
          '掰片/识别': 'Разлом/идентификация',
          '卧式缓存': ' Горизонтальный буфер',
          '磨边前卧式缓存': 'Горизонтальный буфер перед шлифовкой',
          '下片卧式缓存': 'Горизонтальный буфер стекла разгрузки',
          '磨边(冷加工)': 'Шлифовать края (холодная обработка)',
          '1线磨边(冷加工)': 'Шлифовать края 1 линии (холодная обработка)',
          '2线磨边(冷加工)': 'Шлифовать края 2 линии (холодная обработка)',
          '大理片笼': 'Буферная система',
          '钢化': 'Закалка',
          '钢化前': 'Перед закалки',
          '钢化后': 'После закалки',
          '下片台': 'Стол разгрузки',
          '系统管理': 'Управление системой',
          '用户管理': 'Управление пользователем',
          '权限管理': 'Управление полномочиями',
          '角色管理': 'Управление ролью',
     };
  menuData.forEach(menu => {
    menu.menuName = translation[menu.menuName] || menu.menuName;
    // if (menu.children) {
      menu.children && menu.children.forEach(submenu => {
        submenu.menuName = translation[submenu.menuName] || submenu.menuName;
      });
    // }
  });
}
//提取菜单模块列表
let menuList = $ref([])
// request.get('/loadGlass/menu/sysMenu/list').then((res) => {
// onMounted(async () => {
//   try {
//     const res = await request.get('/loadGlass/sys/menu/getMenuTree'); // 假设 request.get 返回 Promise
//     if (res.code == 200) {
//       // 使用 value 属性来修改 ref 引用的值
//       menuList.value = deepClone(res.data);
//       const language = $i18n.locale;
//       if (language === 'en') {
//         replaceChineseWithEnglish(menuList.value); // 传入 ref 的 value
//       }
//       console.log(res.data.token); // 如果 res.data 中有 token 的话
//     } else {
//       ElMessage.warning(res.msg);
//       router.push('/login');
//     }
//   } catch (error) {
//     // 处理请求错误
//     console.error('获取菜单列表时出错:', error);
//   }
// });
request.get('/loadGlass/sys/menu/getMenuTree').then((res) => {
  if (res.code == 200) {
    menuList = deepClone(res.data)
    console.log(response.data.token);
    menuList = res.data
    console.log(language.value)
      if (language.value === 'en') {
        replaceChineseWithEnglish(menuList);
      }
  } else {
    ElMessage.warning(res.msg)
    router.push('/login')
  }
})
const menu = ref(null)
let indexKey = ref(null)
function handleOpen(key) {
  indexKey.value = key
}
watch(
    indexKey,
    (newVal, oldVal) => {
@@ -110,13 +171,20 @@
          <img src="../assets/northGlass.ico"
               alt=""
               style="max-width: 100%;max-height: 100%">
          <h3 style="margin: 1rem  ;font-weight: bold;width: 20vw;"> 欢迎{{ user }}使用北玻MES系统!</h3>
          <h3 style="margin: 1rem  ;font-weight: bold;width: 33vw;"> {{ $t('main.titleFirst') }}{{ user }}{{ $t('main.titleLast') }}</h3>
          <span style="height: 70%;width: 78vw;margin-top: 1rem;">
            <!-- <el-button class="sys-quit"
                       @click="quit"
                       round>
              <el-icon size="large">
                <SwitchButton size=""/>{{ $t('main.quit') }}
              </el-icon>
            </el-button> -->
            <el-button class="sys-quit"
                       @click="quit"
                       round>
              <el-icon size="large">
                <SwitchButton size=""/>退出
                <SwitchButton size=""/>{{ $t('main.quit') }}
              </el-icon>
            </el-button>
          </span>
@@ -124,33 +192,45 @@
      </el-header>
      <div id="line"></div>
      <el-container>
        <el-aside width="160px"
        <!-- <el-aside width="160px"
                  style="height: 99%; background-color: #fff;">
          <div class="menu">
            <div v-for="items in menuList">
              <div class='menu_title'
                   @click="openMenu(items.id)">
                <!-- <span class='indicator' >⌵</span> -->
                <!-- <span class='indicator' >≡</span> -->
                <!-- <img src="../assets/9.png" alt="" style="max-width: 50%;max-height: 50%;"> -->
                <span>☰</span>
                {{ items.menuName }}
              </div>
              <ul class='enter-x-left'
                  v-show="openFlag==items.id">
                <li v-for="menuItem in items.children"
                    style="margin-bottom:2px">
                  <router-link :to="{path:menuItem.url}">
                    {{ menuItem.menuName }}
                  </router-link>
                </li>
              </ul>
            </div>
          </div>
        </el-aside>
        </el-aside> -->
        <el-row :span="20">
            <el-menu :default-active="activePath" class="el-menu-vertical-demo" background-color="#fff">
              <div class="menu">
            <div v-for="items in menuList">
              <div class='menu_title'
                   @click="openMenu(items.id)">
                <span>☰</span>
                {{ items.menuName }}
              </div>
              <ul class='enter-x-left'
                  v-show="openFlag==items.id">
                <li v-for="menuItem in items.children"
                    style="margin-bottom:2px">
                  <router-link :to="{path:menuItem.url}">
                    {{ menuItem.menuName }}
                  </router-link>
                  </li>
                  </ul>
                  </div>
                  </div>
            </el-menu>
          </el-row>
        <el-main>
          <div id="main">
            <router-view></router-view>
@@ -163,6 +243,17 @@
</template>
 
<style scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 200px;
  min-height: 400px;
  text-align: left;
}
#all {
  background-color: #eee;
  height: 100%;
@@ -256,6 +347,7 @@
ul li {
  height: 28px;
  width: 200px;
  line-height: 30px;
  /* background: rgb(128, 128, 128); */
  color: #000000;
@@ -304,7 +396,11 @@
}
.menu_title {
  width: 140px;
  width: 180px;
  /* white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;   */
  height: 45px;
  line-height: 55px;
  /* background: #fafafa; */
UI-Project/src/main.js
@@ -6,22 +6,22 @@
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
//  import i18n from './lang/i18n'
import i18n from '@/lang'
const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate )
// app.use(i18n)
app.use(VXETable)
app.use(pinia)
app.use(router)
app.use(ElementPlus)
app.use(ElementPlus,{
    locale: zhCn,
})
app.use(i18n)
 
app.mount('#app')
UI-Project/src/router/index.js
@@ -1,5 +1,5 @@
import {createRouter, createWebHashHistory} from 'vue-router'
// import i18n from '@/utils/lang'
// import User from '../views/sys/User.vue'
// import Role from '../views/sys/Role.vue'
// import Menu from '../views/sys/Menu.vue'
@@ -187,6 +187,19 @@
          ]
        },
        {
          path: 'GlassStorage',
          name: 'GlassStorage',
          component: () => import('../views/GlassStorage/MaterialRackManagement.vue'),
          children:[
            {
              path: '/GlassStorage/MaterialRackManagement',
              name: 'MaterialRackManagement',
              component: () => import('../views/GlassStorage/MaterialRackManagement.vue')
            }
          ]
         },
         /*----------- 可视化系统 ----------------*/
         {
          path: 'Visualization',
UI-Project/src/views/Caching/cachingbefore.vue
@@ -13,6 +13,9 @@
import { ElMessage, ElMessageBox } from 'element-plus'
//  import LanguageMixin from './lang/LanguageMixin'
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const tableData = ref([])
const slot = ref('')
const adjustedRects = ref([]);
@@ -37,7 +40,7 @@
  }  
}); 
const toggleEnableState = async (row) => {  
  const newState = row.enable_state === 1 ? 0 : 1;
  const newState = row.enable_state === 1 ? 0 : 1;
  // 发送请求到后端更新状态(这里省略了实际的请求逻辑)  
  const response = await request.post('/cacheGlass/edgStorageCage/updateEdgStorageCage', { id: row.id, enablestate: newState });  
  if (response.code === 200) {
@@ -47,19 +50,18 @@
      }  
  row.enable_state = newState;  
}; 
const open = async(row) => {
  try {
const open = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否报缺该条信息?',
      '提示',
      t('sorter.information'),
      t('sorter.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('sorter.yes'),
        cancelButtonText: t('sorter.cancel'),
        type: 'warning',  
      }
      }
    );  
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口
      var url="/cacheGlass/edgStorageCage/edgStorageCageGlass?edgStorageCageId="+row.id;
      console.log(url);
      const response = await request.post(url, {
@@ -68,13 +70,10 @@
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {  
        // 删除失败,您可以处理错误或显示错误信息给用户
      ElMessage.error(response.msg);
        // alert('删除失败:' + deleteResponse.message);
      }  
    }  
  } catch (error) {  
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等
    console.error('发生错误:', error);  
  }  
};   
@@ -111,13 +110,13 @@
        <el-table height="240" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="slot" align="center" label="栅格号" min-width="80" />
          <el-table-column prop="glass_id" align="center" label="玻璃编号" min-width="80" />
          <el-table-column prop="width" align="center" label="宽" min-width="120" />
          <el-table-column prop="height" align="center" label="高" min-width="120" />
          <el-table-column prop="slot" align="center" :label="$t('sorter.gridnumber')" min-width="80" />
          <el-table-column prop="glass_id" align="center" :label="$t('sorter.glassnumber')" min-width="80" />
          <el-table-column prop="width" align="center" :label="$t('sorter.width')" min-width="120" />
          <el-table-column prop="height" align="center" :label="$t('sorter.height')" min-width="120" />
          <el-table-column
            align="center"
            label="启用状态"
            :label="$t('sorter.startstatus')"
            min-width="80"
            prop="enable_state"
          >
@@ -126,17 +125,17 @@
            :type="scope.row.enable_state === 1 ? 'success' : 'danger'"  
            @click="toggleEnableState(scope.row)"  
          >  
            {{ scope.row.enable_state === 1 ? '启用' : '禁用' }}
            {{ scope.row.enable_state === 1 ?  $t('sorter.start') : $t('sorter.disable') }}
          </el-tag>  
        </template> 
          <!-- <template #default="scope">
            <el-tag type="success" >{{ scope.row.enable_state==1?"启用":"未启用"  }}</el-tag>
          </template> -->
          </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column fixed="right" :label="$t('sorter.operate')" align="center" width="200">
            <template #default="scope">
              <!-- <el-button size="mini" type="text" plain @click="handleBindRacka(scope.row)">报缺</el-button> -->
              <el-button size="mini" type="text" plain  @click="open(scope.row)">报缺</el-button>
              <el-button size="mini" type="text" plain  @click="open(scope.row)">{{ $t('sorter.deficiencieste') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
UI-Project/src/views/Caching/cachingun.vue
@@ -1,5 +1,59 @@
<template>
  <div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;">
        <el-table height="240" ref="table"
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="slot" align="center" :label="$t('sorter.gridnumber')" min-width="80" />
          <el-table-column prop="glass_id" align="center" :label="$t('sorter.glassnumber')" min-width="80" />
          <el-table-column prop="width" align="center" :label="$t('sorter.width')" min-width="120" />
          <el-table-column prop="height" align="center" :label="$t('sorter.height')" min-width="120" />
          <el-table-column
          align="center"
            :label="$t('sorter.startstatus')"
            min-width="80"
            prop="enable_state"
          >
          <template #default="scope">
          <el-tag
            :type="scope.row.enable_state === 1 ? 'success' : 'danger'"
            @click="toggleEnableState(scope.row)"
          >
            {{ scope.row.enable_state === 1 ?  $t('sorter.start') : $t('sorter.disable') }}
          </el-tag>
        </template>
          <!-- <template #default="scope">
            <el-tag type="success" >{{ scope.row.enable_state==1?"启用":"未启用"  }}</el-tag>
          </template> -->
          </el-table-column>
          <el-table-column fixed="right" :label="$t('sorter.operate')" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain  @click="open(scope.row)">{{ $t('sorter.deficiencieste') }}</el-button>
              <el-button size="mini" type="text" plain  @click="opena(scope.row)">{{ $t('sorter.updown') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
  <div id="awatch">
    <img src="../../assets/woshihuancun.png" alt="" style="width: 60%;height: 90%;margin-left: 260px;margin-top: 20px;position: relative;">
    <div style="position: absolute; width: 500px;height: 95px;margin-top: -165px;margin-left: 450px;">
    <div
      v-for="(rect, index) in adjustedRects"
      :key="rect"
      :style="{ position: 'absolute',
       top: `${rect.id}px`, left: `10px`, width: `${rect.width}px`, height: `5px`,
      backgroundColor: '#409EFF'
       }"
    >
    </div>
  </div>
</div>
</template>
<script setup>
import {Search} from "@element-plus/icons-vue";
import {Search,Lock,Avatar} from "@element-plus/icons-vue";
import {reactive} from "vue";
import {useRouter} from "vue-router"
const router = useRouter()
@@ -12,6 +66,9 @@
import { ElMessage, ElMessageBox } from 'element-plus'
//  import LanguageMixin from './lang/LanguageMixin'
 
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
// import i18n from '@/i18n';
const tableData = ref([])
const slot = ref('')
const adjustedRects = ref([]);
@@ -36,21 +93,20 @@
    // console.error('Error fetching rects :', error);  
  }  
}); 
const open = async(row) => {
  try {
const open = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否报缺该条信息?',
      '提示',
      t('sorter.information'),
      t('sorter.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('sorter.yes'),
        cancelButtonText: t('sorter.cancel'),
        type: 'warning',  
      }
      }
    );  
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      var url="/cacheGlass/edgStorageCage/edgStorageCageGlass?edgStorageCageId="+row.id;
      var url="/unLoadGlass/downStorage/deleteDownStorageCage?downStorageCageId="+row.id;
      console.log(url);
      const response = await request.post(url, {
        esdId: row.esdId
@@ -59,15 +115,82 @@
      ElMessage.success(response.message);
      } else {  
        // 删除失败,您可以处理错误或显示错误信息给用户  
      ElMessage.error(response.msg);
      ElMessage.error(response.message);
        // alert('删除失败:' + deleteResponse.message); 
      }  
    }  
  } catch (error) {
  }
  catch (error) {
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等  
    console.error('发生错误:', error);  
  }  
};
};
// 人工下片
const opena = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('sorter.infor'),
      t('sorter.prompt'),
      {
        confirmButtonText: t('sorter.yes'),
        cancelButtonText: t('sorter.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/unLoadGlass/downGlassTask/generateOutGlassTask", {
        glassId: row.glass_id
      })
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
        // 删除失败,您可以处理错误或显示错误信息给用户
      ElMessage.error(response.message);
        // alert('删除失败:' + deleteResponse.message);
      }
    }
  }
  catch (error) {
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等
    console.error('发生错误:', error);
  }
};
// const open = async(row) => {
// const { t } = useI18n();
//   try {
//     const confirmMessage = t('sorter.prompt'); // 使用 $t 翻译文本
//     const confirmResult = await ElMessageBox.confirm(
//       confirmMessage,
//       t('sorter.information'),
//       {
//         confirmButtonText: t('sorter.yes'),
//         cancelButtonText: t('sorter.cancel'),
//         type: 'warning',
//       }
//     );
//     if (confirmResult === 'confirm') {
//       // 用户点击了“是”,现在调用删除接口
//       var url="/cacheGlass/edgStorageCage/edgStorageCageGlass?edgStorageCageId="+row.id;
//       console.log(url);
//       const response = await request.post(url, {
//         esdId: row.esdId
//     })
//     if (response.code === 200) {
//       ElMessage.success(response.message);
//       } else {
//         // 删除失败,您可以处理错误或显示错误信息给用户
//       ElMessage.error(response.msg);
//         // alert('删除失败:' + deleteResponse.message);
//       }
//     }
//   }
//   catch (error) {
//     // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等
//     console.error('发生错误:', error);
//   }
// };
const toggleEnableState = async (row) => {  
  const newState = row.enable_state === 1 ? 0 : 1;  
  // 发送请求到后端更新状态(这里省略了实际的请求逻辑)  
@@ -105,62 +228,6 @@
  closeWebSocket();
});
</script>
<template>
  <div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;">
        <el-table height="240" ref="table"
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="slot" align="center" label="栅格号" min-width="80" />
          <el-table-column prop="glass_id" align="center" label="玻璃编号" min-width="80" />
          <el-table-column prop="width" align="center" label="宽" min-width="120" />
          <el-table-column prop="height" align="center" label="高" min-width="120" />
          <el-table-column
          align="center"
            label="启用状态"
            min-width="80"
            prop="enable_state"
          >
          <template #default="scope">
          <el-tag
            :type="scope.row.enable_state === 1 ? 'success' : 'danger'"
            @click="toggleEnableState(scope.row)"
          >
            {{ scope.row.enable_state === 1 ? '启用' : '禁用' }}
          </el-tag>
        </template>
          <!-- <template #default="scope">
            <el-tag type="success" >{{ scope.row.enable_state==1?"启用":"未启用"  }}</el-tag>
          </template> -->
          </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="200">
            <template #default="scope">
              <!-- <el-button size="mini" type="text" plain @click="handleBindRacka(scope.row)">报缺</el-button> -->
              <el-button size="mini" type="text" plain  @click="open(scope.row)">报缺</el-button>
            </template>
        </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
  <div id="awatch">
    <img src="../../assets/woshihuancun.png" alt="" style="width: 60%;height: 90%;margin-left: 260px;margin-top: 20px;position: relative;">
    <div style="position: absolute; width: 500px;height: 95px;margin-top: -165px;margin-left: 450px;">
    <div
      v-for="(rect, index) in adjustedRects"
      :key="rect"
      :style="{ position: 'absolute',
       top: `${rect.id}px`, left: `10px`, width: `${rect.width}px`, height: `5px`,
      backgroundColor: '#409EFF'
       }"
    >
    </div>
  </div>
</div>
</template>
<style scoped>
 
#dt { display:block; float:left;line-height: 20px;margin-left: 100px;}
UI-Project/src/views/GlassStorage/MaterialRackManagement.vue
New file
@@ -0,0 +1,668 @@
<template>
  <div  class="app-container">
    <el-card style="flex: 1; margin-left: 10px; " :loading="loading">
      <div slot="header" class="clearfix" style="display: flex; align-items: center;">
<!-- 左侧按钮组 -->
<div >
  <el-button type="success" size="mini" @click="handleInbound()">入库</el-button>
  <el-button type="success" size="mini" >吊装位入库</el-button>
</div>
<!-- 右侧选择框 -->
<el-form-item style="margin-top: 15px; width: 150px;">
  <el-select v-model="formData2.dzw" placeholder="请选择吊装位">
    <el-option label="吊装位1" value="吊装位1"></el-option>
    <el-option label="吊装位2" value="吊装位2"></el-option>
    <!-- 根据实际情况添加更多选项 -->
  </el-select>
</el-form-item>
</div>
      <el-table
        :data="tableData"
        style="width: 98%; height: 200px"
        @selection-change="handleSelectionChange"
        :header-cell-style="{ background: '#F2F3F5', color: '#1D2129' }"
        ref="table"
        empty-text="No Data"
      >
        <el-table-column prop="location" label="库位号"></el-table-column>
        <el-table-column prop="type" label="类型"></el-table-column>
        <el-table-column prop="length" label="长度(mm)"></el-table-column>
        <el-table-column prop="height" label="高度(mm)"></el-table-column>
        <el-table-column prop="thickness" label="厚度(mm)"></el-table-column>
        <el-table-column prop="quantity" label="数量"></el-table-column>
        <el-table-column prop="entry_time" label="入库时间"></el-table-column>
        <el-table-column prop="batchnumber" label="批次号"></el-table-column>
        <el-table-column
  align="center"
  label="料架状态"
  min-width="80"
  prop="shelf_status"
>
<template #default="scope">
        <el-tag :type="getTagType(scope.row.shelf_status)" @click="toggleStatus(scope.row)">
          {{ scope.row.shelf_status === 1 ? '启用' : '未启用' }}
        </el-tag>
      </template>
</el-table-column>
        <!-- 操作列 -->
        <el-table-column label="操作" width="350">
          <template #default="{ row }">
            <el-button type="primary" size="mini" @click="edithandleRowClick(row)">修改</el-button>
            <el-button type="danger" size="mini" @click="handleDelete(row)">删除</el-button>
            <el-button type="warning" size="mini" @click="handleCheckout(row)">出库</el-button>
            <el-button type="success" size="mini" @click="addglass()">添加原片</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-table
    :data="tasktableData"
    style="width: 98%; height: 150px"
    @selection-change="handleSelectionChange"
    :header-cell-style="{ background: '#F2F3F5', color: '#1D2129' }"
    ref="table"
    empty-text="No Data"
  >
  <template #header>
        <div style="display: flex; align-items: center;">
          <span style="font-size: 16px; font-weight: bold; margin-right: 20px;">任务列表</span>
        </div>
      </template>
    <el-table-column prop="Glassid" label="Glassid"></el-table-column>
    <el-table-column prop="taskDescription" label="任务描述" width="250"></el-table-column>
    <el-table-column prop="glassThickness" label="玻璃厚度"></el-table-column>
    <el-table-column prop="glassFilm" label="玻璃膜系"></el-table-column>
    <el-table-column prop="creationTime" label="创建时间"></el-table-column>
    <el-table-column
      align="center"
      label="任务状态"
      min-width="80"
      prop="taskStatus"
    >
      <template #default="scope">
        <el-tag :type="getTagType2(scope.row.taskStatus)">
          {{ scope.row.taskStatus == 'completed' ? '完成' : '进行中' }}
        </el-tag>
      </template>
    </el-table-column>
    <!-- 操作列 -->
    <el-table-column label="操作" width="350">
      <template #default="{ row }">
        <el-button type="primary" size="mini" @click="handleRestart(row)">重新开始</el-button>
        <el-button type="danger" size="mini" @click="handleDeletetask(row)">删除任务</el-button>
        <el-button type="success" size="mini" @click="handleComplete(row)">任务完成</el-button>
      </template>
    </el-table-column>
  </el-table>
    </el-card>
    <div ref="chart" id="chart" style="width: 100%; height: 250px;"></div>
    <!-- 入库对话框 -->
    <el-dialog
      title="入库"
      v-model="dialogVisible"
      width="30%"
      :before-close="handleCloseDialog"
    >
      <el-form :model="formData" ref="form" label-width="80px">
        <el-form-item label="进库料架">
          <el-select v-model="formData.shelf" placeholder="请选择进库料架">
            <el-option label="A1" value="A1"></el-option>
            <el-option label="B2" value="B2"></el-option>
            <!-- 根据实际情况添加更多选项 -->
          </el-select>
        </el-form-item>
        <el-form-item label="颜色膜系">
          <el-select v-model="formData.color" placeholder="请选择颜色膜系">
            <el-option label="Red" value="Red"></el-option>
            <el-option label="Blue" value="Blue"></el-option>
            <!-- 根据实际情况添加更多选项 -->
          </el-select>
        </el-form-item>
        <el-form-item label="宽度">
          <el-input v-model.number="formData.width" placeholder="请输入宽度"></el-input>
        </el-form-item>
        <el-form-item label="高度">
          <el-input v-model.number="formData.height" placeholder="请输入高度"></el-input>
        </el-form-item>
        <el-form-item label="厚度">
          <el-input v-model.number="formData.thickness" placeholder="请输入厚度"></el-input>
        </el-form-item>
        <el-form-item label="数量">
          <el-input v-model.number="formData.quantity" placeholder="请输入数量"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleConfirmInbound">确 定</el-button>
      </div>
    </el-dialog>
    <el-dialog title="添加原片"  v-model="dialogVisible3" width="50%">
    <el-form :model="formData3" ref="form" label-width="80px">
      <el-form-item label="颜色膜系">
        <el-input v-model="formData.selectedColor" readonly style="width: 250px; height: 35px; font-size: 20px"></el-input>
        <el-dropdown @command="handleCommand">
          <span class="el-dropdown-link">
            选择<i class="el-icon-arrow-down el-icon--right"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item v-for="color in colors" :key="color['0_glass_id']" :command="color['0_glass_id']">
              {{ color['0_glass_id'] }}
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </el-form-item>
      <el-form-item label="长度">
        <el-input v-model="formData.wid" required style="width: 250px; font-size: 20px" @focus="clearInput('wid')"></el-input>
      </el-form-item>
      <el-form-item label="高度">
        <el-input v-model="formData.heig" required style="width: 250px; font-size: 20px" @focus="clearInput('heig')"></el-input>
      </el-form-item>
      <el-form-item label="厚度">
        <el-input v-model="formData.thinkness" required style="width: 250px; font-size: 20px" @focus="clearInput('thinkness')"></el-input>
      </el-form-item>
      <el-form-item label="数量">
        <el-input-number v-model="formData.num" required :min="0" :max="9000" style="width: 250px; font-size: 20px" @focus="clearInput('num')"></el-input-number>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible3 = false">关闭</el-button>
      <el-button type="primary" @click="submitForm">提交</el-button>
    </span>
  </el-dialog>
  <el-dialog title="编辑" v-model="editdialogVisible" width="30%" @close="edithandleDialogClose">
      <el-form :model="editForm" ref="editFormRef" label-width="80px">
        <el-form-item label="数量">
          <el-input v-model="editForm.quantity"></el-input>
        </el-form-item>
        <el-form-item label="批次号">
          <el-input v-model="editForm.batchnumber"></el-input>
        </el-form-item>
      </el-form>
      <div  class="dialog-footer">
        <el-button @click="editdialogVisible = false">取消</el-button>
        <el-button type="primary" @click="editsaveEdit">保存</el-button>
      </div>
    </el-dialog>
    <!-- <div ref="chart" id="chart" style="width: 100%; height: 400px;"></div> -->
  </div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'; // 导入 Vue 3 的模块
import * as echarts from 'echarts';
import { ElMessage, ElMessageBox } from 'element-plus'
    const loading = ref(false);
    const tableData = ref([
    {
        location: '1',
        type: 'Type A',
        length: '100',
        height: '50',
        thickness: '10',
        quantity: '5',
        entry_time: '2024-06-19 10:00:00',
        batchnumber:"444",
        shelf_status: 1
      },
      {
        location: '2',
        type: 'Type B',
        length: '120',
        height: '60',
        thickness: '12',
        quantity: '10',
        entry_time: '2024-06-19 10:00:00',
        batchnumber:"444",
        shelf_status: 0
      },
      {
        location: '3',
        type: 'Type B',
        length: '120',
        height: '60',
        thickness: '12',
        quantity: '10',
        entry_time: '2024-06-19 10:00:00',
        batchnumber:"444",
        shelf_status: 1
      },
      {
        location: '4',
        type: 'Type B',
        length: '120',
        height: '60',
        thickness: '12',
        quantity: '10',
        entry_time: '2024-06-19 10:00:00',
        batchnumber:"444",
        shelf_status: 1
      },
      {
        location: '5',
        type: 'Type B',
        length: '120',
        height: '60',
        thickness: '12',
        quantity: '10',
        entry_time: '2024-06-19 10:00:00',
        batchnumber:"444",
        shelf_status: 1
      }
      // Add more data as needed
    ]);
   const getTagType2 =(status) => {
      switch (status) {
        case 'completed':
          return 'success';
        case 'in-progress':
          return 'info';
        case 'warning':
          return 'warning';
        case 'danger':
          return 'danger';
        default:
          return '';
      }
    }
    const getTagType =(status) => {
      return status === 1 ? 'success' : 'danger';
      // 根据状态值决定标签类型,这里假设状态为1时为成功(绿色),否则为失败(红色)
    }
    const toggleStatus = (row) => {
      // 切换料架状态的逻辑
      row.shelf_status = 1 - row.shelf_status; // Toggle between 0 and 1
      // 此处可以添加保存状态的逻辑,比如调用 API 更新数据
    };
   const tasktableData=ref([
    {
          Glassid: 'G001',
          taskDescription: '从吊装位【99】到仓位【56】',
          taskStatus: 'in-progress',
          glassThickness: '5mm',
          glassFilm: '膜系A',
          creationTime: '2024-06-19 10:00:00'
        },
        {
          Glassid: 'G002',
          taskDescription: '从吊装位【99】到仓位【56】',
          taskStatus: 'completed',
          glassThickness: '10mm',
          glassFilm: '膜系B',
          creationTime: '2024-06-19 11:00:00'
        }
        ]);
    const dialogVisible = ref(false);
    const formData = ref({
      shelf: '',
      color: '',
      width: '',
      height: '',
      thickness: '',
      quantity: ''
    });
    const formData2 = ref({
      dzw: '',
    });
    const handleDelete = (row) => {
  // 使用 Element UI 的 MessageBox.confirm 方法进行二次确认
  ElMessageBox.confirm('确定要执行删除操作吗?', '确认删除', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 点击确认按钮的回调,执行出库操作
    console.log('执行删除操作', row);
  }).catch(() => {
    // 点击取消按钮的回调,不执行任何操作
    console.log('取消删除操作');
  });
};
    const handleCheckout = (row) => {
  // 使用 Element UI 的 MessageBox.confirm 方法进行二次确认
  ElMessageBox.confirm('确定要执行出库操作吗?', '确认出库', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 点击确认按钮的回调,执行出库操作
    console.log('执行出库操作', row);
  }).catch(() => {
    // 点击取消按钮的回调,不执行任何操作
    console.log('取消出库操作');
  });
};
    const handleInbound = () => {
      // 打开入库对话框
      dialogVisible.value = true;
    };
    const handleCloseDialog = () => {
      // 关闭对话框时重置表单数据
      formData.value = {
        shelf: '',
        color: '',
        width: '',
        height: '',
        thickness: '',
        quantity: ''
      };
      dialogVisible.value = false;
    };
    const handleConfirmInbound = () => {
      // 处理确认入库逻辑,可以在这里提交表单或者执行其他操作
      console.log('Confirm Inbound:', formData.value);
      // 关闭对话框
      dialogVisible.value = false;
    };
    const dialogVisible3 = ref(false);
    const colors = ref([
      { '0_glass_id': 'Red' },
      { '0_glass_id': 'Green' },
      { '0_glass_id': 'Blue' }
      // Add more colors as needed
    ]);
    const formData3 = ref({
      selectedColor: '',
      wid: '',
      heig: '',
      thinkness: '',
      num: ''
    });
    const addglass = () => {
      // 打开入库对话框
      dialogVisible3.value = true;
    };
    const handleCommand = (command) => {
      formData.value.selectedColor = command;
    };
    const clearInput = (field) => {
      formData.value[field] = '';
    };
    const submitForm = () => {
      console.log('提交数据:', formData.value);
      dialogVisible3.value = false;
      // Add your submit logic here
    };
    const editdialogVisible = ref(false);
    const editForm = ref({
      quantity: '',
      batchnumber: ''
    });
    const editFormRef = ref(null);
    let currentRow = ref(null);
    // 处理行点击事件
    const edithandleRowClick = (row) => {
      currentRow.value = row;
      editForm.value.quantity = row.quantity.toString();
      editForm.value.batchnumber = row.batchnumber;
      editdialogVisible.value = true;
      console.log(editForm.value)
    };
    // 添加保存编辑内容
    const editsaveEdit = () => {
      if (!currentRow.value) return;
      // 更新当前行数据
      currentRow.value.quantity = parseInt(editForm.value.quantity);
      currentRow.value.batchnumber = editForm.value.batchnumber;
      // 关闭对话框
      editdialogVisible.value = false;
    };
    // 对话框关闭时重置编辑表单和当前行数据
    const edithandleDialogClose = () => {
      editForm.value.quantity = '';
      editForm.value.batchnumber = '';
      currentRow.value = null;
    };
    const handleRestart = (row) => {
  // 使用 Element UI 的 MessageBox.confirm 方法进行二次确认
  ElMessageBox.confirm('确定要执行重新开始操作吗?', '确认重新开始', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 点击确认按钮的回调
    console.log('执行重新开始操作', row);
  }).catch(() => {
    // 点击取消按钮的回调,不执行任何操作
    console.log('取消重新开始操作');
  });
};
const handleDeletetask = (row) => {
  // 使用 Element UI 的 MessageBox.confirm 方法进行二次确认
  ElMessageBox.confirm('确定要执行删除任务操作吗?', '确认删除任务', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 点击确认按钮的回调
    console.log('执行删除任务操作', row);
  }).catch(() => {
    // 点击取消按钮的回调,不执行任何操作
    console.log('取消删除任务操作');
  });
};
const handleComplete = (row) => {
  // 使用 Element UI 的 MessageBox.confirm 方法进行二次确认
  ElMessageBox.confirm('确定要执行任务完成操作吗?', '确认任务完成', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 点击确认按钮的回调
    console.log('执行任务完成操作', row);
  }).catch(() => {
    // 点击取消按钮的回调,不执行任何操作
    console.log('取消任务完成操作');
  });
};
    let chartInstance = null;
onMounted(() => {
  // Initialize the chart
  chartInstance = echarts.init(document.getElementById('chart'));
  // Simulated data for demonstration
  const chartData = {
    labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
    datasets: [
      { name: '使用情况统计', data: [{ remaining: 4, total: 5 }, { remaining: 9, total: 10 }, { remaining: 0, total: 30 }, { remaining: 0, total: 10 },{ remaining: 4, total: 5 }] }
    ]
  };
  const options = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['使用情况统计']
    },
    xAxis: {
      type: 'category',
      data: chartData.labels
    },
    yAxis: {
      type: 'value'
    },
    series: chartData.datasets.map(item => ({
      name: item.name,
      type: 'bar',
      stack: '总量',
      label: {
        show: true,
        position: 'inside',
        formatter: '{c}%'
      },
      data: item.data.map(dataItem => ({
        value: (dataItem.remaining / dataItem.total * 100).toFixed(2), // 计算剩余量占比,保留两位小数
        remaining: dataItem.remaining,
        total: dataItem.total,
        itemStyle: {
          color: getColorByRemaining(dataItem.remaining, dataItem.total)
        }
      }))
    }))
  };
  function getColorByRemaining(remaining, total) {
    // 根据剩余量与总量的比例,设置不同的颜色逻辑
    const percentage = remaining / total;
    if (percentage >= 0.8) {
      return '#FF6666'; // Red
    } else if (percentage >= 0.5) {
      return '#FFCC66'; // Yellow
    } else {
      return '#66CC66'; // Green
    }
  }
  // Set options and render chart
  if (chartInstance) {
    chartInstance.setOption(options);
  }
});
onBeforeUnmount(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});
const handleSelectionChange = (selection) => {
  console.log('Selection changed:', selection);
};
</script>
<style scoped>
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden; /* 禁止出现滚动条 */
}
.app-container {
  flex-direction: column;
  height: 100vh; /* 使用视口高度 */
}
.custom-dialog {
  max-height: 90vh; /* 最大高度为视口高度的90% */
  overflow-y: auto; /* 对话框内部出现垂直滚动条 */
}
</style>
UI-Project/src/views/Identify/identify.vue
@@ -1,6 +1,6 @@
<template>  
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;" v-loading="loading">
      <el-scrollbar height="700px">
      <el-scrollbar height="600px">
  <div id="app" style="margin-top: 20px;">  
    <div  
      :style="{ width: `${olWidth}px`, height: `${olHeight}px`,position: 'relative' }"  
@@ -26,12 +26,12 @@
  </div> 
  <!-- 点击弹出 -->
  <el-dialog v-model="blind" top="30vh" width="15%" style="text-align: center;">
        <el-button type="warning" plain :icon="Delete" @click="handleDamage(currentGlassId)"  style="width: 120px;margin-left: 10px;">
          破损
        <el-button type="warning" plain :icon="Delete" @click="handleDamage(currentGlassId)"  style="width: 140px;margin-left: 10px;">
          {{ $t('order.dilapidation') }}
        </el-button>
        <el-button  type="danger" plain @click="handleManualTake(currentGlassId)" style="width: 120px;margin-top: 10px;">
        <el-button  type="danger" plain @click="handleManualTake(currentGlassId)" style="width: 140px;margin-top: 10px;">
          <el-icon class="el-icon--right"><Upload /></el-icon>
          人工拿走</el-button>
          {{ $t('order.Takeaway') }}</el-button>
  </el-dialog> 
   </div>
  </div>  
@@ -45,6 +45,9 @@
import request from "@/utils/request"
import { WebSocketHost ,host} from '@/utils/constants'
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const blind = ref(false)
const olWidth = ref(); 
const olHeight = ref();
@@ -76,8 +79,8 @@
      adjustedRects.value = rawRects.map(rect => ({  
        ...rect, // 复制原始对象的其他属性  
        x_axis: (rect.x_axis*100) * 0.004, // 将x值除以3
        y_axis: (rect.y_axis*100) * 0.004,
        x_axis: (rect.x_axis*100) * 0.003, // 将x值除以3
        y_axis: (rect.y_axis*100) * 0.003,
        width: (rect.width*100) * 0.002 ,
        widtha: rect.width ,
        heighta: rect.height ,
@@ -183,8 +186,8 @@
  // adjustedRects.value = data.currentCutTerritory[0]
  adjustedRects.value = data.currentCutTerritory[0].map(rect => ({  
        ...rect, // 复制原始对象的其他属性  
        x_axis: (rect.x_axis*100) * 0.004, // 将x值除以3
        y_axis: (rect.y_axis*100) * 0.004,
        x_axis: (rect.x_axis*100) * 0.003, // 将x值除以3
        y_axis: (rect.y_axis*100) * 0.003,
        width: (rect.width*100) * 0.002 ,
        widtha: rect.width ,
        heighta: rect.height ,
UI-Project/src/views/LoginView.vue
@@ -5,12 +5,17 @@
import {ElMessage} from 'element-plus'
import request from '@/utils/request'
import userInfo from '@/stores/userInfo'
import { useI18n } from 'vue-i18n'
const store = userInfo()
let ruleFormRef = ref<FormInstance>()
const router = useRouter()
const route = useRoute()
const { t } = useI18n()
let language = ref(localStorage.getItem('lang') || 'zh')
const changeLanguage = () =>{
  localStorage.setItem('lang',language.value)
  location.reload()
}
const userForm = reactive({
  userName: '',
  password: '',
@@ -22,7 +27,7 @@
 
const validateUser = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入你的账号'))
    callback(new Error(t('login.userErr')))
  } else {
    callback()
  }
@@ -30,7 +35,7 @@
 
const validatePass = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入你的密码'))
    callback(new Error(t('login.pwErr')))
  } else {
    callback()
  }
@@ -56,7 +61,7 @@
              console.log(res.data)
 
              router.push('/main')
              ElMessage.success(`登录成功`)
              ElMessage.success(t('login.loginSuccessful'))
            } else {
              ElMessage.error(res['msg'])
              store.$patch({
@@ -67,7 +72,7 @@
            }
          })
          .catch((error) => {
            ElMessage.error('服务器连接失败')
            ElMessage.error(t('main.connectErr'))
            store.$patch({
              user: null,
              })
@@ -113,26 +118,35 @@
          <img src="../../src/assets/3.png">
        </div>
        <div style="position: absolute; left: 15vw; top: 22vw; font-size: 55px;color: rgba(29, 33, 41, 1);">
          北玻MES系统
          {{ $t('northglassMESsystem') }}
        </div>
      </div>
      <div id="div-login">
        <!--语言切换按钮-->
        <el-select
            @change="changeLanguage"
            v-model="language"
            placeholder=" "
            style="float: right;width: 9rem">
          <el-option value="zh"  label="中文" />
          <el-option value="en"  label="Русский язык" />
        </el-select>
        <el-form @submit.native.prevent
                 ref="ruleFormRef"
                 :model="userForm"
                 status-icon
                 :rules="rules">
          <div id="center">
            <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">账号</div>
            <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">{{ $t('login.user') }}</div>
            <el-form-item prop="userId">
              <el-input style="width: 340px;"
                        v-model="userForm.userName"
                        type="text"
                        autocomplete="off"
                        :prefix-icon="Avatar"
                        placeholder="请输入账号"/>
                        :placeholder="$t('login.userErr')"/>
            </el-form-item>
            <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">密码</div>
            <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">{{ $t('login.password') }}</div>
            <el-form-item prop="pass">
              <el-input style="width: 340px;"
                        v-model="userForm.password"
@@ -140,7 +154,8 @@
                        autocomplete="off"
                        :prefix-icon="Lock"
                        show-password
                        placeholder="请输入密码"/>
                        :placeholder="$t('login.pwErr')"
                       />
            </el-form-item>
            <el-form-item id="submitForm">
              <el-button :loading="loginLoadings"
@@ -148,12 +163,12 @@
                         native-type="submit"
                         @click="submitForm(ruleFormRef)"
                         @keyup.enter.native="keyDown(e)"
                         plain>登录
                         plain>{{ $t('login.login') }}
              </el-button>
              <el-button :loading="registerLoadings"
                         type="primary"
                         @click="register"
                         plain>注册
                         plain>{{ $t('login.register') }}
              </el-button>
 
            </el-form-item>
UI-Project/src/views/PurchaseReturn/purchaseReturn.vue
@@ -3,49 +3,58 @@
import {reactive} from "vue";
import {useRouter} from "vue-router"
import request from "@/utils/request"
// import { ref } from 'vue'
import { ref, onMounted, onBeforeUnmount } from 'vue';  
import { WebSocketHost ,host} from '@/utils/constants'
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const dialogFormVisible = ref(true)
const dialogFormVisiblea = ref(false)
const dialogFormVisibleb = ref(false)
const width = ref(); // 用于存储process_id的响应式引用
const height = ref(); // 用于存储process_id的响应式引用
const width = ref();
const height = ref();
const adjustedRects = ref([]);
const adjustedRects2 = ref([]);
const adjustedRectsa = ref([]);
const adjustedRectsb = ref([]);
// 进炉中
const socketUrl = `ws://${WebSocketHost}:${host}/api/temperingGlass/api/talk/temperingGlass`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
  // 更新 tableData 的数据
// 进炉中
  adjustedRects.value =  data.intoGlass[0].map(rect => ({  
        ...rect, // 复制原始对象的其他属性
        xcoordinate: rect.xCoordinate * 0.5, // 将x值除以3
        ycoordinate: rect.ycoordinate * 0.5,
        width: rect.width * 0.4,
        height: rect.height * 0.4,
        ...rect,
        xcoordinate: rect.xCoordinate * 0.3,
        ycoordinate: rect.ycoordinate * 0.3,
        width: rect.width * 0.2,
        height: rect.height * 0.2,
        widtha: rect.width,
        heighta: rect.height,
      }));
  adjustedRects2.value =  data.intoGlass2[0].map(rect => ({
        ...rect,
        xcoordinate: rect.xCoordinate * 0.3,
        ycoordinate: rect.ycoordinate * 0.3,
        width: rect.width * 0.2,
        height: rect.height * 0.2,
        widtha: rect.width,
        heighta: rect.height,
      })); 
      console.log(data.intoGlass[0]);
  // 进炉前
      adjustedRectsa.value = data.waitingGlass[0].map(rect => ({  
        ...rect, // 复制原始对象的其他属性  
        xcoordinate: rect.xCoordinate * 0.5, // 将x值除以3
        xcoordinate: rect.xCoordinate * 0.5,
        ycoordinate: rect.ycoordinate * 0.5,
        width: rect.width * 0.4,
        height: rect.height * 0.4,
        widtha: rect.width,
        heighta: rect.height,
        state: rect.state
      }));
      }));
    // 已出炉
      adjustedRectsb.value = data.outGlass[0].map(rect => ({  
        ...rect, // 复制原始对象的其他属性  
        xcoordinate: rect.xCoordinate * 0.5, // 将x值除以3
        xcoordinate: rect.xCoordinate * 0.5,
        ycoordinate: rect.ycoordinate * 0.5,
        width: rect.width * 0.4,
        height: rect.height * 0.4,
@@ -55,66 +64,60 @@
      }));  
};
onMounted(() => {
  // fetchFlowCardId();
  // fetchTableData(); // 获取数据
  initializeWebSocket(socketUrl, handleMessage);
});
onBeforeUnmount(() => {
  console.log("关闭了")
  closeWebSocket();
});
</script>
<template>
<template>
  <div style="margin-top: 10px;">
     <el-button style="margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisible = true;dialogFormVisiblea = false;dialogFormVisibleb = false;">进炉中</el-button>
     <el-button style="margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisiblea = true;dialogFormVisible = false;dialogFormVisibleb = false;" >进炉前</el-button>
    <el-button  id="searchButton" type="success" @click="dialogFormVisibleb = true;dialogFormVisible = false;dialogFormVisiblea = false">已出炉玻璃</el-button>
     <el-button style="margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisible = true;dialogFormVisiblea = false;dialogFormVisibleb = false;">{{ $t('processCard.intofurnace') }}</el-button>
     <el-button style="margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisiblea = true;dialogFormVisible = false;dialogFormVisibleb = false;" >{{ $t('processCard.beforefurnace') }}</el-button>
    <el-button  id="searchButton" type="success" @click="dialogFormVisibleb = true;dialogFormVisible = false;dialogFormVisiblea = false">{{ $t('processCard.outfurnace') }}</el-button>
<div v-if="dialogFormVisible" >
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;height: 700px;" v-loading="loading">
<div style="width: 49%;float: left;background-color: #f4f4f5;height: 650px;">
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;height: 600px;" v-loading="loading">
<div style="width: 49%;float: left;background-color: #f4f4f5;height: 550px;">
  <el-scrollbar height="630px">
    <div v-for="(group, groupId) in groupedRects" :key="groupId" style="position: relative;">
    <div  style="position: relative;width: 1400px;">  
      <div  
      v-for="(rect, index) in adjustedRects"
      v-for="(rect, index) in adjustedRects"
      :key="index"  
      class="rect"
      class="rect"
      :style="{ position: 'absolute',  top: `${rect.ycoordinate}px`, left: `${rect.xcoordinate}px`, width: `${rect.width}px`, height: `${rect.height}px`  }"  
    >
     <div  class="centered-text">
    <div >{{ rect.flowcardId }}</div>  
    <div style="margin-top: 50px;margin-left: -50px;">{{ rect.widtha }}*{{ rect.heighta }}</div>  
  </div>
  </div>
   </div>
  </div>
   </div>
   </el-scrollbar>
  </div>
<div style="width: 49%;float: right;background-color: #f4f4f5;height: 650px;">
  <el-scrollbar height="630px">
<div style="width: 49%;float: right;background-color: #f4f4f5;height: 550px;">
  <el-scrollbar height="550px">
    <div  style="position: relative;width: 1400px;">  
      <div  
      v-for="(rect, index) in adjustedRects"
      v-for="(rect, index) in adjustedRects2"
      :key="index"  
      class="rect"
      class="rect"
      :style="{ position: 'absolute',  top: `${rect.ycoordinate}px`, left: `${rect.xcoordinate}px`, width: `${rect.width}px`, height: `${rect.height}px`  }"  
    >
     <div  class="centered-text">
    <div >{{ rect.flowcardId }}</div>  
    <div style="margin-top: 50px;margin-left: -50px;">{{ rect.widtha }}*{{ rect.heighta }}</div>  
  </div>
  </div>
  </div>
   </div>
   </el-scrollbar>
</div>
   </el-card>
    </div>
<div v-if="dialogFormVisiblea">
  <!-- 进炉前 -->
  <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;" v-loading="loading">
      <el-scrollbar height="630px">
      <el-scrollbar height="550px">
    <div  style="position: relative;width: 1400px;">  
      <div  
      v-for="(rect, index) in adjustedRectsa"  
@@ -133,8 +136,9 @@
   </el-card>
</div>
<div v-if="dialogFormVisibleb">
  <!-- 已出炉 -->
  <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;" v-loading="loading">
      <el-scrollbar height="630px">
      <el-scrollbar height="550px">
    <div  style="position: relative;width: 1400px;">  
      <div  
      v-for="(rect, index) in adjustedRectsb"  
@@ -154,7 +158,6 @@
</div>
  </div>
</template>
<style scoped>
#boxa{
  border: 1px solid rgb(119, 116, 116);
UI-Project/src/views/PurchaseReturn/purchaseStorage.vue
@@ -56,7 +56,7 @@
  <div style="margin-top: 10px;">
<div>
    <el-card style="margin-left: 10px;margin-top: 10px;margin-right: 10px;" v-loading="loading">
    <el-scrollbar height="630px">
    <el-scrollbar height="600px">
    <div  style="position: relative;width: 1400px;">  
      <div  
      v-for="(rect, index) in adjustedRects"
UI-Project/src/views/RegisterView.vue
@@ -7,6 +7,10 @@
import { Lock,Avatar } from '@element-plus/icons-vue'
  // import {Avatar, UserFilled} from "@element-plus/icons-vue";
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
  const router = useRouter()
  const route = useRoute()
  let loginLoadings= ref(false)
@@ -23,9 +27,9 @@
  /*方法*/
  const checkName = (rule: any, value: any, callback: any) => {
    if (value.trim() === '') {
      callback(new Error('姓名不能为空'))
      callback(new Error(t('login.namea')))
    }else if(value.length>16){
      callback(new Error('长度不能超过16'))
      callback(new Error(t('login.len')))
    }else{
      callback()
    }
@@ -33,9 +37,9 @@
  const checkPassword = (rule: any, value: any, callback: any) => {
    if (value.trim() === '') {
      callback(new Error('密码不能为空'))
      callback(new Error(t('login.passnull')))
    }else if(value.length>16 || value.length<6){
      callback(new Error('密码长度不能低于6或超过16'))
      callback(new Error(t('login.leng')))
    }else{
      callback()
    }
@@ -43,11 +47,11 @@
  const checkConfirmPassword = (rule: any, value: any, callback: any) => {
    if (value.trim() === '') {
      callback(new Error('确认密码不能为空'))
      callback(new Error(t('login.spwn')))
    }else if(value !== register.passWord){
      callback(new Error('两次密码不相同'))
      callback(new Error(t('login.depass')))
    }else if(value.length>16 || value.length<6){
      callback(new Error('密码长度不能低于6或超过16'))
      callback(new Error(t('login.leng')))
    }else{
      callback()
    }
@@ -88,14 +92,14 @@
              })
            })
            ElMessage.success(`注册成功`)
            ElMessage.success(t('register.registerSuccessful'))
            loginLoadings.value=false
          } else {
            ElMessage.error(res['msg'])
            return false
          }
        }).catch(error => {
          ElMessage.error("服务器连接失败")
          ElMessage.error(t('main.connectErr'))
          loginLoadings.value=false
          return false
        })
@@ -107,11 +111,6 @@
                path:'/login',
              })
  }
  // console.log(route.params)
</script>
<template>
@@ -123,7 +122,7 @@
        <img src="../../src/assets/3.png">
      </div> 
       <div style="position: absolute; left: 15vw; top: 22vw; font-size: 55px;color: rgba(29, 33, 41, 1);">
        北玻MES系统
        {{ $t('northglassMESsystem') }}
      </div>
    </div>
    <div id="div-login">
@@ -135,33 +134,33 @@
            :rules="rules"
            label-width="75px"
        >
          <div id="title">注册新用户</div>
          <div id="title">{{ $t('register.newuserregister') }}</div>
        <div id="center">
            <!-- <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">姓名</div> -->
          <el-form-item prop="userName" label="姓名:">
          <el-form-item prop="userName" :label="$t('register.name')">
            <el-input
            style="width: 200px;"
                v-model="register.userName"
                type="text"
                autocomplete="off"
                :prefix-icon="Avatar"
                placeholder="请输入姓名"
                :placeholder="$t('register.inputname')"
            />
          </el-form-item>
            <!-- <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">密码</div> -->
          <el-form-item prop="passWord" label="密码:">
          <el-form-item prop="passWord" :label="$t('register.password')">
            <el-input
            style="width: 200px;"
                v-model="register.passWord"
                type="password"
                autocomplete="off"
                :prefix-icon="Lock"
                placeholder="请输入密码"
                :placeholder="$t('register.pwErr')"
                show-password
            />
          </el-form-item>
            <!-- <div style="color: rgba(78, 89, 105, 1);margin-bottom: 10px;">确认密码</div> -->
          <el-form-item prop="confirmPassword" label="确认密码:">
          <el-form-item prop="confirmPassword" :label="$t('register.passwordation')">
            <el-input
            style="width: 200px;"
                v-model="register.confirmPassword" 
@@ -169,7 +168,7 @@
                :prefix-icon="Lock"
                autocomplete="off"
                show-password
                placeholder="请确认密码"
                :placeholder="$t('register.pwErration')"
            />
          </el-form-item>
          <el-form-item id="submitForm">
@@ -178,13 +177,13 @@
                type="primary"
                @click="submitForm(ruleFormRef)"
                plain
            >确认注册
            >{{ $t('register.registration') }}
            </el-button>
            <el-button
                type="primary"
                @click="toLogin"
                plain
            >取消
            >{{ $t('register.false') }}
            </el-button>
          </el-form-item>
@@ -196,25 +195,6 @@
</template>
<style scoped>
/* #main-div{
  position: absolute;
  left:75%;
  top:45%;
  transform: translate(-50%, -50%);
} */
/* #register{
  background-color: #fff;
  width: 32vw;
  height: 35vh;
  box-shadow: 0 8px 16px 0 rgba(0,0,0,0), 0 6px 5px 0 rgba(0,0,0,0.19);
  display:flex;
  align-items:center;
  justify-content:center;
  min-height: 280px;
} */
/* .el-form{
  max-width: 300px;
} */
#div-login{
  margin-top: 5%;
  /* margin-top: 20%; */
UI-Project/src/views/Returns/returns.vue
@@ -5,6 +5,8 @@
const router = useRouter()
import type { TableColumnCtx } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const dialogFormVisible = ref(false)
const blind = ref(false)
const blinda = ref(false)
@@ -25,7 +27,8 @@
const selectedValuea = ref('');  
const selectedValueb = ref('');
const selectedValuec = ref(''); 
const upstatus = ref('上片机手动状态:'); // 假设这个用于显示自动/手动状态
// const upstatus = ref('上片机手动状态:'); // 假设这个用于显示自动/手动状态
const upstatus = ref(t('basicData.machineaa'));
const cuttingMachine = ref(''); // 假设这个用于存储后端返回的状态值(0或1)  
const cuttingMachineStatusColor = ref('#911005'); // 用于动态设置i标签的背景色 
const inKageWord = ref(0); // 用于存储要传递给接口的inKageWord值 
@@ -260,7 +263,7 @@
  else  {
      ElMessage({
        type: 'info',
        message: '第二行和第四行的高必须大于2700才能保存!',
        message: t('basicData.pause'),
      })
    }
   
@@ -320,8 +323,8 @@
      const uniqueThicknesses = new Set(response.data.map(item => item.thickness));  
  
      selectOptions.value = Array.from(uniqueWidths).map(width => ({ 
      value: width, // 假设这是你想要作为value的属性
      label: width, // 假设这是你想要显示的label
      value: width,
      label: width,
    }));  
      selectOptionsa.value = Array.from(uniqueHeights).map(height => ({ 
      value: height, 
@@ -375,7 +378,7 @@
  }
    } else if (markingMachineStatus.value === '#911005' || cuttingMachineStatus.value === '#911005') {  
      // 提示用户打标机未就绪  
      ElMessage.warning('请确认打标机和切割机的就绪状态!');
      ElMessage.warning(t('basicData.pausea'));
    } 
}
// 暂停
@@ -400,7 +403,7 @@
    else  {
      ElMessage({
        type: 'info',
        message: '工程号不能为空!',
        message: t('basicData.infonull'),
      })
    }
}
@@ -433,7 +436,7 @@
    else  {
      ElMessage({
        type: 'info',
        message: '工程号不能为空!',
        message: t('basicData.infonull'),
      })
    }
}
@@ -446,13 +449,13 @@
function getStatusText(state: number) {
  switch (state) {
    case 0:  
      return '等待中';
      return t('basicData.waiting');
    case 1:  
      return '上片中';
      return t('basicData.up');
    case 2:  
      return '上片中';
    return t('basicData.up');
    case 100:  
      return '已完成';
    return t('basicData.finish');
  }  
}  
function getStatusType(state: number) {  
@@ -498,27 +501,24 @@
const toggleEnableState = async (row: any) => {  
  // 检查 id 是否为空  
  if (!row.id) {  
    ElMessage.error('该工程未保存到上片表!');
    ElMessage.error(t('basicData.updatanull'));
    return; // 如果 id 为空,则不执行后续操作  
  }  
  const newState = row.state === 100 ? 0 : 100;  
  try {  
    // 发送请求到后端更新状态  
    const response = await request.post('/loadGlass/up-patten-usage/updateGlassState', { id: row.id, state: newState });  
    if (response.code === 200) {  
      ElMessage.success(response.message);  
      row.state = newState;
    } else {  
      ElMessage.error(response.message);  
    }  
  } catch (error) {  
    // 处理请求错误  
    console.error('更新玻璃状态请求失败:', error);
    ElMessage.error('更新玻璃状态时发生错误');
    ElMessage.error(t('basicData.glassnull'));
  }  
};  
const wsUrl = `ws://${WebSocketHost}:${host}/api/loadGlass/api/talk/loadGlass`;
const ws = new WebSocket(wsUrl);  
ws.onopen = () => {  
@@ -547,7 +547,7 @@
    if (data && Array.isArray(data.InkageStatus) && data.InkageStatus.length > 0) {  
      const status = data.InkageStatus[0]; 
      cuttingMachine.value = status; 
      upstatus.value = status === '1' ? '上片机联机状态:' : '上片机手动状态:';
            upstatus.value = status === '1' ? t('basicData.machine') : t('basicData.machineaa');
      cuttingMachineStatusColor.value = status === '1' ? 'green' : '#911005';  
      inKageWord.value = status === '1' ? 0 : 1;  
    } else {  
@@ -565,7 +565,7 @@
  );  
    if (response.code == 200) {  
      const status = response.data.status; 
      upstatus.value = status === '1' ? '上片机联机状态:' : '上片机手动状态:';
      upstatus.value = status === '1' ? t('basicData.machine') : t('basicData.machineaa');
      cuttingMachineStatusColor.value = status === '1' ? 'green' : '#911005';  
      // 显示成功消息  
      ElMessage.success(response.message);  
@@ -583,20 +583,20 @@
<template>
  <div>
    <div id="dotClass">
      <div>打标机就绪状态:</div>
      <div>{{ $t('basicData.laserprinting') }}</div>
    <i :style="{ marginTop: '2px', backgroundColor: markingMachineStatus, width: '18px', height: '18px', borderRadius: '50%', display: 'block' }"></i>  
    <el-button @click="confirmMarkingMachine" style="margin-left: 30px;margin-top: -3px;">确认</el-button>
    <div style="margin-left: 70px;">切割机就绪状态:</div>
    <el-button @click="confirmMarkingMachine" style="margin-left: 30px;margin-top: -3px;">{{ $t('basicData.yes') }}</el-button>
    <div style="margin-left: 70px;">{{ $t('basicData.cuttingmachine') }}</div>
    <i :style="{ marginTop: '2px', backgroundColor: cuttingMachineStatus, width: '18px', height: '18px', borderRadius: '50%', display: 'block' }"></i>  
    <el-button @click="confirmCuttingMachine" style="margin-left: 30px;margin-top: -3px;" >确认</el-button>
    <el-button @click="confirmCuttingMachine" style="margin-left: 30px;margin-top: -3px;" >{{ $t('basicData.yes') }}</el-button>
    <div style="margin-left: 70px;">{{ upstatus  }} </div>
    <i :style="{ marginTop: '2px', backgroundColor: cuttingMachineStatusColor, width: '18px', height: '18px', borderRadius: '50%', display: 'block' }"></i>  
    <el-button @click="confirmCutting" style="margin-left: 30px;margin-top: -3px;" >切换</el-button>
    <el-button @click="confirmCutting" style="margin-left: 30px;margin-top: -3px;" >{{ $t('basicData.change') }}</el-button>
   
  </div>
    <el-button style="margin-top: 5px;margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisible = true">选择工程</el-button>
    <el-button style="margin-top: 5px;margin-left: 20px;" id="searchButton" type="primary" @click="handleBind">开始上片</el-button>
    <el-button style="margin-top: 5px;margin-left: 20px;"  id="searchButton" type="warning" @click="handleBinda">暂停</el-button>
    <el-button style="margin-top: 5px;margin-left: 15px;"   id="searchButton" type="primary" @click="dialogFormVisible = true">{{ $t('basicData.selectproject') }}</el-button>
    <el-button style="margin-top: 5px;margin-left: 20px;" id="searchButton" type="primary" @click="handleBind">{{ $t('basicData.startloading') }}</el-button>
    <el-button style="margin-top: 5px;margin-left: 20px;"  id="searchButton" type="warning" @click="handleBinda">{{ $t('basicData.stop') }}</el-button>
    <!-- <el-button style="margin-top: 5px;margin-left: 20px;"  id="searchButton" type="danger" @click="handleBindb">停止任务</el-button> -->
    
    <el-card style="flex: 1;margin-left: 10px;margin-top: 15px;" v-loading="loading">
@@ -607,12 +607,12 @@
     :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
      :data="tableData"
    >
    <el-table-column prop="engineeringId" label="工程号" width="200" align="center"/>
      <el-table-column prop="width" label="原片宽" align="center"/>
      <el-table-column prop="height" label="原片高" align="center"/>
      <el-table-column prop="filmsId" label="膜系" align="center"/>
      <el-table-column prop="layoutSequence" label="数量" align="center"/>
      <el-table-column prop="thickness" label="厚度" align="center"/>
    <el-table-column prop="engineeringId" :label="$t('basicData.projectnumber')" width="200" align="center"/>
      <el-table-column prop="width" :label="$t('basicData.glasswidth')" align="center"/>
      <el-table-column prop="height" :label="$t('basicData.glassheight')" align="center"/>
      <el-table-column prop="filmsId" :label="$t('basicData.coatingtypes')" align="center"/>
      <el-table-column prop="layoutSequence" :label="$t('basicData.quantity')" align="center"/>
      <el-table-column prop="thickness" :label="$t('basicData.thickness')" align="center"/>
      <!-- <el-table-column
            align="center"
            label="状态"
@@ -626,7 +626,7 @@
      </template>  -->
      <el-table-column
          align="center"
            label="启用状态"
            :label="$t('basicData.startstatus')"
            min-width="80"
            prop="state"
          >
@@ -635,34 +635,34 @@
            :type="scope.row.state === 100 ? 'success' : 'warning'"  
            @click="toggleEnableState(scope.row)"  
          >  
            {{ scope.row.state === 100 ? '通过' : '等待中' }}
            {{ scope.row.state === 100 ? $t('basicData.pass') : $t('basicData.waiting') }}
          </el-tag>  
        </template> 
          </el-table-column>
    </el-table>
      </div>
    </el-card>
  <el-dialog v-model="blind" top="30vh" width="25%" title="是否开始上片?" >
  <el-dialog v-model="blind" top="30vh" width="25%" :title="$t('basicData.startfilm')">
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handle">
          确认
          {{ $t('basicData.confirm') }}
        </el-button>
        <el-button @click="blind = false">取消</el-button>
        <el-button @click="blind = false">{{ $t('basicData.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="blinda" top="30vh" width="25%" title="是否暂停?" >
  <el-dialog v-model="blinda" top="30vh" width="25%" :title="$t('basicData.whetherpause')">
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handlea">
          确认
          {{ $t('basicData.confirm') }}
        </el-button>
        <el-button @click="blinda = false">取消</el-button>
        <el-button @click="blinda = false">{{ $t('basicData.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="blindb" top="30vh" width="25%" title="是否停止任务?" >
  <!-- <el-dialog v-model="blindb" top="30vh" width="25%" title="是否停止任务?" >
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleb">
@@ -671,31 +671,31 @@
        <el-button @click="blindb = false">取消</el-button>
      </div>
    </template>
  </el-dialog>
  </el-dialog> -->
      <div id="parent">
        <img src="../../assets/shangpianji.png" alt="" style="max-width: 20%;max-height: 20%;margin-top: 20px;margin-left: 500px;">
        <div id="overlay" v-show="flake"></div>
        <div id="overlaya" v-show="flakea"></div>
      </div>
      <div style="margin-top: -350px;margin-left: 650px;">
        <el-table :data="tableDataa" border style="width: 70%"
        <el-table :data="tableDataa" border style="width: 85%"
     :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
        >
          <el-table-column prop="workstationId" align="center" label="工位" min-width="50" />
          <el-table-column prop="patternWidth" align="center" label="宽" min-width="80" />
          <el-table-column prop="patternHeight" align="center" label="高" min-width="80" />
          <el-table-column prop="filmsId" align="center" label="膜系" min-width="80" />
          <el-table-column prop="number" align="center" label="数量" min-width="80" />
          <el-table-column fixed="right" label="操作" align="center" width="150">
          <el-table-column prop="workstationId" align="center" :label="$t('basicData.station')" min-width="60" />
          <el-table-column prop="patternWidth" align="center" :label="$t('basicData.width')" min-width="80" />
          <el-table-column prop="patternHeight" align="center" :label="$t('basicData.height')" min-width="80" />
          <el-table-column prop="filmsId" align="center" :label="$t('basicData.coatingtypes')" min-width="80" />
          <el-table-column prop="number" align="center" :label="$t('basicData.quantity')" min-width="80" />
          <el-table-column fixed="right" :label="$t('basicData.operate')" align="center" width="150">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">添加</el-button>
              <el-button size="mini" type="text" plain @click="handleBindRacka(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">{{ $t('basicData.add') }}</el-button>
              <el-button size="mini" type="text" plain @click="handleBindRacka(scope.row)">{{ $t('basicData.delete') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
    </div>
    
  <el-dialog v-model="add" top="23vh" width="45%" title="添加原片" >
  <el-dialog v-model="add" top="23vh" width="45%" :title="$t('basicData.addglass')" >
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form  size="mini" label-width="150px">
      <el-form label-width="70px" label-position="right">
@@ -703,12 +703,12 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="宽:" :required="true" style="width: 14vw">
              <el-form-item :label="$t('basicData.widtha')" :required="true" style="width: 14vw">
               <el-select  
                      v-model="selectedValue"  
                      filterable  
                      clearable  
                      placeholder="请选择宽"
                      :placeholder="$t('basicData.selectwidth')"
                      style="width: 220px"  
                      @input="handleInputChangea"  
                    >  
@@ -725,12 +725,12 @@
          <el-col :span="9">
            <div id="dta" style="font-size: 15px;">
        <div>
          <el-form-item label="高:" :required="true" style="width: 14vw">
          <el-form-item :label="$t('basicData.heighta')" :required="true" style="width: 14vw">
            <el-select  
                      v-model="selectedValuea"  
                      filterable  
                      clearable  
                      placeholder="请选择高"
                      :placeholder="$t('basicData.selectheight')"
                      style="width: 220px"  
                      @input="handleInputChangea"  
                    >  
@@ -749,12 +749,12 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="膜系:" :required="true" style="width: 14vw;">
              <el-form-item :label="$t('basicData.coatingtypesa')"  :required="true" style="width: 14vw;">
                <el-select  
                      v-model="selectedValueb"  
                      filterable  
                      clearable  
                      placeholder="请选择膜系"
                      :placeholder="$t('basicData.selectcoatingtypes')"
                      style="width: 220px"  
                      @input="handleInputChangea"  
                    >  
@@ -770,12 +770,12 @@
          <el-col :span="9">
            <div id="dta" style="font-size: 15px;">
        <div>
              <el-form-item label="厚度:" :required="true" style="width: 14vw">
              <el-form-item :label="$t('basicData.thicknessa')" :required="true" style="width: 14vw">
                <el-select  
                      v-model="selectedValuec"  
                      filterable  
                      clearable  
                      placeholder="请选择厚度"
                      :placeholder="$t('basicData.selectthickness')"
                      style="width: 220px"  
                      @input="handleInputChangea"  
                    >  
@@ -794,8 +794,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="数量:" :required="true" style="width: 14vw;">
                <el-input  v-model="number" autocomplete="off" />
              <el-form-item :label="$t('basicData.quantitya')" :required="true" style="width: 14vw;">
                <el-input :placeholder="$t('basicData.selectquantity')" v-model="number" autocomplete="off" />
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -805,31 +805,31 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleConfirm">
          确认
          {{ $t('basicData.confirm') }}
        </el-button>
        <el-button @click="add = false">取消</el-button>
        <el-button @click="add = false">{{ $t('basicData.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="adda" top="30vh" width="25%" title="是否删除该条信息?" >
  <el-dialog v-model="adda" top="30vh" width="25%" :title="$t('basicData.deletemessage')">
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleConfirma">
          确认
          {{ $t('basicData.confirm') }}
        </el-button>
        <el-button @click="adda = false">取消</el-button>
        <el-button @click="adda = false">{{ $t('basicData.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
        </div>
  <el-dialog v-model="dialogFormVisible" top="24vh" width="30%" title="工程" >
  <el-dialog v-model="dialogFormVisible" top="24vh" width="30%" :title="$t('basicData.project')" >
    <div style="margin-left: 50px;margin-bottom: 10px;">
      <el-form-item label="工程号:" :required="true">
      <el-form-item :label="$t('basicData.projectnumber')" :required="true">
        <el-select  
           v-model="selectedProjectNo"  
           filterable  
           clearable  
           placeholder="请选择工程"
           :placeholder="$t('basicData.plselectproject')"
           style="width: 220px"  
           @input="handleInputChange"  
         >  
@@ -845,9 +845,9 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleup">
          确认
          {{ $t('basicData.confirm') }}
        </el-button>
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button @click="dialogFormVisible = false">{{ $t('basicData.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
UI-Project/src/views/Slicecage/slicecage.vue
@@ -1,10 +1,13 @@
<script lang="ts" setup>
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
import {Search} from "@element-plus/icons-vue";
import {reactive} from "vue";
import {useRouter} from "vue-router"
const router = useRouter()
import request from "@/utils/request"
import { WebSocketHost ,host} from '@/utils/constants'
import { ref, onMounted , onBeforeUnmount} from "vue";
import { ref, onMounted , onBeforeUnmount, reactive, computed } from "vue";
import { initializeWebSocket, closeWebSocket } from '@/utils/WebSocketService';
import { ElMessage, ElMessageBox } from 'element-plus'
import { tr } from "element-plus/es/locale";
@@ -15,10 +18,30 @@
const tableDatab = ref([])
const tableDatac = ref([])
const tableDatad = ref([])
const tableDataf = ref([])
const tableDatae = ref([])
const adjustedRects = ref([]);
const height = ref([]);
const project = ref([]);
const adjustedRectsa = ref([]);
const adjustedRectsb = ref([]);
const adjustedRectsc = ref([]);
const adjustedRectsd = ref([]);
const adjustedRectse = ref([]);
const adjustedRectsf = ref([]);
const adjustedRectsg = ref([]);
const currentRow = reactive({}); // 当前行的数据
const add = ref(false)
const flowCardId = ref('');
const gap = ref('');
const glassId = ref('');
const glassType = ref('');
const height = ref('');
const sequence = ref('');
const state = ref('');
const temperingFeedSequence = ref('');
const temperingLayoutId = ref('');
const thickness = ref('');
const width = ref('');
const carposition1 = ref(60);
const carposition2 = ref(220);
const carposition3 = ref(60);
@@ -46,136 +69,99 @@
const cell6=ref(true);
const cell7=ref(true);
const cell8=ref(true);
const currentPage4 = ref(4)
const pageSize4 = ref(100)
const selectedRow = ref(null); // 存储选中的行数据
const dialogForm = () => {
  ElMessageBox.confirm(
    '确定要急停吗?',
    '提示',
    {
      confirmButtonText: '是',
      cancelButtonText: '否',
      type: 'warning',
    // 当前页码和每页显示的条数
    const currentPage = ref(1);
    const itemsPerPage = computed(() => {
      if (currentPage.value === 1) {
        return 21;
      } else if (currentPage.value === 2) {
        return 21;
      } else if (currentPage.value === 3) {
        return 21;
      } else if (currentPage.value === 4) {
        return 20;
      } else if (currentPage.value === 5) {
        return 21;
      } else if (currentPage.value === 6) {
        return 25;
      } else if (currentPage.value === 7) {
        return 51;
      } else if (currentPage.value === 8) {
        return 25;
      } else {
        return 25; // 默认值,可以根据实际需求修改
      }
    });
    // 计算分页后的数据
    const paginatedUsers = computed(() => {
      const startIndex = calculateStartIndex();
      const endIndex = startIndex + itemsPerPage.value;
      return tableData.value.slice(startIndex, endIndex);
    });
    // 计算当前页的起始索引
    function calculateStartIndex() {
      let index = 0;
      for (let i = 1; i < currentPage.value; i++) {
        if (i === 1) {
          index += 21;
        } else if (i === 2) {
          index += 21;
        } else if (i === 3) {
          index += 21;
        }else if (i === 4) {
          index += 20;
        }else if (i === 5) {
          index += 21;
        }else if (i === 6) {
          index += 25;
        }else if (i === 7) {
          index += 51;
        }else if (i === 8) {
          index += 25;
        } else {
          index += 25;
        }
      }
      return index;
    }
  )
    .then(() => {
      ElMessage({
        type: 'success',
        message: '急停成功!',
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '急停失败',
      })
    })
}
  var timer=setInterval(() => {
    // console.log(million.value,million1.value);
    million.value+=1;
    if(million.value-million1.value!==12){
      if(million.value-million1.value>=2){
        if(carposition1.value==220){
          timers1.value=false;
        }else if(carposition1.value==60){
          timers1.value=true;
        }
        if(timers1.value==true){
          carposition1.value=carposition1.value+16;
        }else{
          carposition1.value=carposition1.value-16;
        }
        if(carposition2.value==220){
          timers2.value=false;
        }else if(carposition2.value==60){
          timers2.value=true;
        }
        if(timers2.value==true){
          carposition2.value+=16;
        }else{
          carposition2.value-=16;
        }
      }else{
    // 上一页和下一页方法
    const prevPage = () => {
      if (currentPage.value > 1) {
        currentPage.value--;
      }
    }else{
      million1.value=million.value;
    };
    
      if(cellshow1.value==true){
        cellshow1.value=false;
      }else{
        cellshow1.value=true;
    const nextPage = () => {
      if (currentPage.value < totalPages.value) {
        currentPage.value++;
      }
      if(cellshow2.value==true){
        cellshow2.value=false;
      }else{
        cellshow2.value=true;
      }
    }
  }, 1000);
  var timer=setInterval(() => {
    // console.log(million3.value,million4.value);
    million3.value+=1;
    if(million3.value-million4.value!==12){
      if(million3.value-million4.value>=2){
        if(carposition3.value==260){
          timers3.value=false;
        }else if(carposition3.value==60){
          timers3.value=true;
        }
        if(timers3.value==true){
          carposition3.value=carposition3.value+20;
        }else{
          carposition3.value=carposition3.value-20;
        }
        if(carposition4.value==260){
          timers4.value=false;
        }else if(carposition4.value==60){
          timers4.value=true;
        }
        if(timers4.value==true){
          carposition4.value+=20;
        }else{
          carposition4.value-=20;
        }
      }else{
      }
    }else{
      million4.value=million3.value;
      if(cellshow5.value==true){
        cellshow5.value=false;
      }else{
        cellshow5.value=true;
      }
      if(cellshow3.value==true){
        cellshow3.value=false;
      }else{
        cellshow3.value=true;
      }
      if(cellshow4.value==true){
        cellshow4.value=false;
      }else{
        cellshow4.value=true;
      }
    }
  }, 1000);
    };
    // 总页数计算
    const totalPages = computed(() => {
      // let total = 0;
      // for (let i = 1; i <= users.value.length; i++) {
      //   if (i === 1) {
      //     total += 1;
      //   } else if (i === 2) {
      //     total += 2;
      //   } else if (i === 3) {
      //     total += 5;
      //   } else {
      //     total += 10;
      //   }
      // }
      return 9;
    });
const getTableRow = (row,type) =>{
  switch (type) {
    case 'edit' :{
@@ -189,8 +175,293 @@
    }
  }
}
const handleBindRack = (row) => {
  selectedRow.value = row; // 更新选中的行数据
  currentRow.deviceId  = row.deviceId; // 直接设置响应式属性
  currentRow.slot = row.slot;
  window.localStorage.setItem('deviceId', row.deviceId)
  window.localStorage.setItem('slot', row.slot)
  add.value = true; // 打开绑定架子对话框
};
// 搜索
const searchout = async () => {
  try {
    const response = await request.post('/cacheVerticalGlass/bigStorageCageDetails/selectBigStorageCageDetails',{
      glassId:glassId.value
    });
    if (response.code == 200) {
      // 绑定成功,处理逻辑
      tableDataf.value = response.data;
      ElMessage.success(response.message);
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.message);
    }
  } catch (error) {
    // 处理错误
    console.error(error);
  }
};
// 是否禁用
const toggleEnableState = async (row) => {
  const newState = row.enableState === 1 ? 0 : 1;
  console.log(row.slot);
  console.log(row.enableState);
  var url="/cacheVerticalGlass/bigStorageCage/updateStorageCageDisabled?slot="+row.slot + "&enableState=" + newState;
      console.log(url);
      const response = await request.get(url)
  if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
  row.enableState = newState;
};
 // 删除
 const opena = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.deletemessage'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      // 用户点击了“是”,现在调用删除接口
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/deleteBigStorageCageDetails",row)
    if (response.code === 200) {
     tableData.value = response.data;
     ElMessage.success(response.message);
      } else {
        // 删除失败,您可以处理错误或显示错误信息给用户
      ElMessage.error(response.message);
        // alert('删除失败:' + deleteResponse.message);
      }
    }
  } catch (error) {
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等
    console.error('发生错误:', error);
  }
};
 // 破损
 const broke = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.broke'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/damageBigStorageCageDetails?status="+0, row)
    if (response.code === 200) {
     tableData.value = response.data;
     ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
 // 拿走
 const brokec = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.brokeb'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/damageBigStorageCageDetails?status="+1, row)
    if (response.code === 200) {
     tableData.value = response.data;
     ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
 // 出片
 const outfil = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.outfil'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      // 用户点击了“是”,现在调用删除接口
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/outBigStorageCageDetails", row)
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
 // 出片队列破损
 const brokea = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.broke'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/cacheVerticalGlass/temperingGlassInfo/damageTemperingGlassInfo?status="+0, row)
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// 出片队列拿走
const brokeb = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.brokeb'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/cacheVerticalGlass/temperingGlassInfo/damageTemperingGlassInfo?status="+1, row)
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// 出片队列删除
const deletea = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.deletemessage'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const dataToSend = {
        ...row,
        status: 1
      };
      const response = await request.post("/cacheVerticalGlass/temperingGlassInfo/deleteTemperingGlassInfo", dataToSend)
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// 完成任务
const finish = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.fin'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/finishBigStorageCageDetails", row)
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// 确认添加
const finisha = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('searchOrder.sureadda'),
      t('searchOrder.prompt'),
      {
        confirmButtonText: t('searchOrder.yes'),
        cancelButtonText: t('searchOrder.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
    let deviceId = window.localStorage.getItem('deviceId')
    let slot = window.localStorage.getItem('slot')
      const dataToSend = {
        ...row,
        deviceId: deviceId,
        slot: slot
      };
      const response = await request.post("/cacheVerticalGlass/bigStorageCageDetails/insertBigStorageCageDetails", dataToSend)
    if (response.code === 200) {
      tableData.value = response.data;
      add.value = false;
      ElMessage.success(response.message);
      glassId.value = '';
      tableDataf.value = '';
      } else {
      ElMessage.error(response.message);
      }
    }
  } catch (error) {
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等
    console.error('发生错误:', error);
  }
};
function handleRowClick(row) {
  selectedRow.value = row; // 更新选中的行数据
}
const socketUrl = `ws://${WebSocketHost}:${host}/api/cacheVerticalGlass/api/talk/slicecage`;
// 定义消息处理函数,更新 receivedData 变量
const handleMessage = (data) => {
@@ -200,40 +471,72 @@
  tableData.value = data.bigStorageCageInfo[0]
  tableDatab.value = data.temperingGlassInfoList[0]
  tableDatae.value = data.bigStorageCageUsage[0]
  adjustedRects.value = data.bigStorageCageInfo1[0]
  // adjustedRects.value = data.bigStorageCageInfo1[0].map(rect => ({
  //           ...rect, // 复制原始对象的其他属性
  //           height: rect.length *0.5,
  //         }));
  // adjustedRects.value = data.bigStorageCageInfo1[0]
  window.localStorage.setItem('length', data.bigStorageCageInfo1[0].length)
  let length = window.localStorage.getItem('length')
  console.log(length);
  adjustedRects.value = data.bigStorageCageInfo1[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
    let small = data.bigStorageCageInfo1[0]
    console.log(small[0].bigStorageCageDetails);
adjustedRectsa.value = data.bigStorageCageInfo2[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectsb.value = data.bigStorageCageInfo3[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectsc.value = data.bigStorageCageInfo4[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectsd.value = data.bigStorageCageInfo5[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectse.value = data.bigStorageCageInfo6[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectsf.value = data.bigStorageCageInfo7[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
adjustedRectsg.value = data.bigStorageCageInfo8[0].map(rect => ({
            ...rect,
            height: 20/length,
            top: 29/length
          }));
};
// function getRectHeight(length: number) {
//   return length > 0 ? 29 / length : 29;
// }
// 初始化 WebSocket,并传递消息处理函数
onMounted(() => {
  // fetchFlowCardId();
  // fetchTableData(); // 获取数据
  initializeWebSocket(socketUrl, handleMessage);
});
function getStatusType(enableState: number) {  
  switch (enableState) {  
    case 0:
      return 'warning';
    case 1:
    case 100:
      return 'success';  
    case 102:
      return 'warning';
  }  
}  
function getStatusText(enableState: number) {
  switch (enableState) {
    case 0:
      return '禁用';
    case 1:
      return '启用';
    case 100:
      return t('searchOrder.zailong');
    case 102:
      return t('searchOrder.rengongxp');
  }  
}
function getStatusTypea(ishorizontal: number) {  
@@ -247,9 +550,9 @@
function getStatusTexta(ishorizontal: number) {
  switch (ishorizontal) {
    case 0:  
      return '不接受';
      return t('searchOrder.noaccept');
    case 1:  
      return '接受';
    return t('searchOrder.accept');
  }  
}
function getStatusTypeb(state: number) {  
@@ -263,11 +566,11 @@
function getStatusTextb(state: number) {
  switch (state) {
    case 0:  
      return '出片完成';
      return t('searchOrder.filmcomplete');
    case 1:  
      return '等待中';
      return t('searchOrder.waiting');
    case 2:  
      return '等待中';
    return t('searchOrder.waiting');
  }  
}
onBeforeUnmount(() => {
@@ -277,31 +580,39 @@
</script>
 
<template>
  <div style="height: 700px;">
    <!-- <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="primary" @click="dialogFormVisible = true">手动进片</el-button> -->
    <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="primary" @click="dialogFormVisiblea = true">理片笼信息</el-button>
    <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="success" @click="dialogFormVisibleb = true">出片队列</el-button>
    <!-- <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="danger">终止进片</el-button> -->
    <!-- <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="danger">终止出片</el-button> -->
    <!-- <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="danger"  @click="dialogForm">软急停</el-button> -->
  <div style="height: 600px;">
    <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="primary" @click="dialogFormVisiblea = true">{{ $t('searchOrder.cageinformation') }}</el-button>
    <el-button style="margin-top: 5px;margin-left: 10px;"   id="searchButton" type="success" @click="dialogFormVisibleb = true">{{ $t('searchOrder.productionqueue') }}</el-button>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 5px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;max-height: 100px;">
        <el-table height="100%" ref="table" 
        :data="tableDatac" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="bigStorageCageOutTask.glassId" align="center" label="出片玻璃ID" min-width="80" />
          <el-table-column prop="bigStorageCageOutTask.startSlot" align="center" label="起始位置" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.endSlot" align="center" label="目标位置" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.trainNumber" align="center" label="车次" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.serialNumber" align="center" label="序号" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.taskState" align="center" label="任务状态" min-width="157">
          <template #default="scope">
            <el-tag type="success" >{{ scope.row.bigStorageCageOutTask.taskState==0?"等待进片":"进行中"  }}</el-tag>
          <el-table-column prop="bigStorageCageOutTask.glassId" align="center" :label="$t('searchOrder.outputglassID')" min-width="100" />
          <el-table-column prop="bigStorageCageOutTask.startSlot" align="center" :label="$t('searchOrder.startposition')" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.endSlot" align="center" :label="$t('searchOrder.targetlocation')" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.trainNumber" align="center" :label="$t('searchOrder.trips')" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.serialNumber" align="center" :label="$t('searchOrder.number')" min-width="120" />
          <el-table-column prop="bigStorageCageOutTask.taskState" align="center" :label="$t('searchOrder.taskstatus')" min-width="157">
          <template #default="scope">
            <el-tag type="success" >{{ scope.row.bigStorageCageOutTask.taskState==0? $t('searchOrder.filmenter') : $t('searchOrder.infilm') }}</el-tag>
          </template>
          </el-table-column>
          <el-table-column fixed="right" label="结束任务" align="center" width="150">
          <el-table-column prop="id" align="center" :label="$t('searchOrder.tabid')" min-width="150"/>
          <el-table-column prop="deviceId" align="center" :label="$t('searchOrder.tid')" min-width="100"/>
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="100"/>
          <el-table-column prop="glassId" align="center" :label="$t('searchOrder.glassID')" min-width="100"/>
          <el-table-column prop="sequence" align="center" :label="$t('searchOrder.pieceingrid')" min-width="150"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="100"/>
          <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="100"/>
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="100"/>
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="100"/>
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="100"/>
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100"/>
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120"/>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="100"/>
          <el-table-column fixed="right" :label="$t('searchOrder.endtask')" align="center" width="150">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">完成任务</el-button>
              <el-button size="mini" type="text" plain @click="finish(scope.row)">{{ $t('searchOrder.completetask') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
@@ -312,18 +623,31 @@
        <el-table height="100%" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableDatad" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="bigStorageCageFeedTask.glassId" align="center" label="进片玻璃ID" min-width="80" />
          <el-table-column prop="bigStorageCageFeedTask.tragetSlot" align="center" label="目标位置" min-width="120" />
          <el-table-column prop="bigStorageCageFeedTask.glassId" align="center" :label="$t('searchOrder.intoglassid')" min-width="100" />
          <el-table-column prop="bigStorageCageFeedTask.targetSlot" align="center" :label="$t('searchOrder.targetlocation')" min-width="120" />
          <!-- <el-table-column prop="task_type" align="center" label="任务类型" min-width="120" />没有返回字段 -->
          <el-table-column prop="bigStorageCageFeedTask.taskState" align="center" label="任务状态" min-width="120">
          <el-table-column prop="bigStorageCageFeedTask.taskState" align="center" :label="$t('searchOrder.taskstatus')" min-width="120">
          <template #default="scope">
            <el-tag type="success" >{{ scope.row.bigStorageCageFeedTask.taskState==0?"等待进片":"进行中"  }}</el-tag>
            <el-tag type="success" >{{ scope.row.bigStorageCageFeedTask.taskState==0? $t('searchOrder.filmenter') : $t('searchOrder.infilm') }}</el-tag>
          </template>
          </el-table-column>
          <el-table-column prop="bigStorageCageFeedTask.line" align="center" label="线路" min-width="120" />
          <el-table-column fixed="right" label="结束任务" align="center" width="150">
          <el-table-column prop="bigStorageCageFeedTask.line" align="center" :label="$t('searchOrder.line')" min-width="120" />
          <el-table-column prop="id" align="center" :label="$t('searchOrder.tabid')" min-width="150"/>
          <el-table-column prop="deviceId" align="center" :label="$t('searchOrder.tid')" min-width="100"/>
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="100"/>
          <el-table-column prop="glassId" align="center" :label="$t('searchOrder.glassID')" min-width="100"/>
          <el-table-column prop="sequence" align="center" :label="$t('searchOrder.pieceingrid')" min-width="150"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="100"/>
          <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="100"/>
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="100"/>
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="100"/>
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="100"/>
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100"/>
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120"/>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="100"/>
          <el-table-column fixed="right" :label="$t('searchOrder.endtask')" align="center" width="150">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">完成任务</el-button>
              <el-button size="mini" type="text" plain @click="finish(scope.row)">{{ $t('searchOrder.completetask') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
@@ -333,17 +657,14 @@
            <div v-for="(item, index) in tableDatae" :key="index" id="occupy">  
               <el-col style="text-align:left;font-weight: bold;">#{{ item.device_id }}</el-col>  
               <el-col style="text-align:left;display:flex;justify-content: space-between;align-items: center;">  
                 <span>使用率</span><span>{{ item.percentage }}</span>
                 <span>{{ $t('searchOrder.Usage') }}</span><span>{{ item.percentage }}</span>
               </el-col>  
               <hr style="width:80%;margin: 0 auto;" />  
               <el-col style="text-align:left;display:flex;justify-content: space-between;align-items: center;">  
                 <span>空闲(格子数)</span><span>{{ item.count }}</span>
                 <span>{{ $t('searchOrder.free') }}</span><span>{{ item.count }}</span>
               </el-col>  
             </div>  
    </div>
    <!-- <div id="awatch">
  <img src="../../assets/cp.png" alt="" style="width: 70%;height: 70%;margin-left: 160px;">
</div> -->
<!-- // 父级框 -->
<div class="img-dlpl" >
    <div class="img-car1" :style="'z-index:999;left:247px;top:' + carposition1 + 'px;position:absolute;'">
@@ -359,229 +680,441 @@
    <div class="img-car4" :style="'z-index:999;left:704px;top:' + carposition4 + 'px;position:absolute;'">
      <div v-show="cellshow4" style="margin-top:10px;width:200px;height:5px;background-color:#409EFF;"></div>
    </div>
    <div v-show="cell1" style="width: 227px;height: 29px;position: absolute;top:55px;left: 465px;">
    <div style="position: relative;">
    <div v-show="cell1" style="width: 227px;height: 29px;position: relative;top:55px;left: 465px;">
      <div  
      v-for="(item, index) in adjustedRects"
      :key="index"
      v-for="(rect, index) in adjustedRects"
      :key="rect.id"
      :style="{
       top: `1px`, width: `227px`,
      backgroundColor: '#409EFF',
      height: `height`+ `px`
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"  
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
      <!-- <div
        v-for="(item, index) in adjustedRects"
        height: `${rect.height}px`,
        :key="index"
        :style="{
        width: '227px',
        height: '1px',
        backgroundColor: '#409EFF',
        top: '1px'
      }"
      >
      </div> -->
    </div>
   <!-- <div v-show="cell2" style="width: 227px;height: 29px;position: absolute;top:86px;left: 465px;background-color: #409EFF;">
 <div v-show="cell2" style="width: 227px;height: 29px;position: relative;top:56px;left: 465px;">
  <div
      v-for="(rect, index) in adjustedRectsa"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
     <div v-show="cell3" style="width: 227px;height: 29px;position: absolute;top:117px;left: 465px;background-color: #409EFF;">
    </div>
  <div v-show="cell4" style="width: 227px;height: 29px;position: absolute;top:148px;left: 465px;background-color: #409EFF;">
  <div v-show="cell3" style="width: 227px;height: 29px;position: absolute;top:117px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectsb"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
  <div v-show="cell5" style="width: 227px;height: 29px;position: absolute;top:208px;left: 465px;background-color: #409EFF;">
    </div>
  <div v-show="cell6" style="width: 227px;height: 29px;position: absolute;top:238px;left: 465px;background-color: #409EFF;">
  <div v-show="cell4" style="width: 227px;height: 29px;position: absolute;top:148px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectsc"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
  <div v-show="cell7" style="width: 227px;height: 29px;position: absolute;top:269px;left: 465px;background-color: #409EFF;">
    </div>
  <div v-show="cell8" style="width: 227px;height: 29px;position: absolute;top:300px;left: 465px;background-color: #409EFF;">
    </div> -->
  <div v-show="cell5" style="width: 227px;height: 29px;position: absolute;top:208px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectsd"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
    </div>
  <div v-show="cell6" style="width: 227px;height: 29px;position: absolute;top:238px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectse"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
    </div>
  <div v-show="cell7" style="width: 227px;height: 29px;position: absolute;top:269px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectsf"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
    </div>
  <div v-show="cell8" style="width: 227px;height: 29px;position: absolute;top:300px;left: 465px;">
    <div
      v-for="(rect, index) in adjustedRectsg"
      :key="rect.id"
      :style="{
        // display:'flex',
       position: 'absolute',
       width: '227px',
      //  backgroundColor: 'red',
       left: '0px',
       top: index*rect.top+`px`,
       height: `${rect.height}px`,
       }"
    >
    <div
      v-for="(rects, index) in rect.bigStorageCageDetails"
      :key="rects"
      :style="{
        float:'left',
       width: '18px',
       height: `${rect.height}px`,
       backgroundColor: '#911005',
      // border:'1px solid black',
       top: '0px',
       marginRight: rects.gap/5000*227+'px'
       }"
    >
      </div>
    </div>
    </div>
</div>
</div>
  </div>
<el-dialog v-model="dialogFormVisible" top="12vh" width="85%" title="请确认玻璃信息" >
  <div style="margin-left: 50px;margin-bottom: 10px;">
    <div style="display: flex;">
    <p style="margin-top: 4px;">确认状态:</p>
    <el-button style="margin-left: 10px;size: mini;" type="success">允许</el-button>
    <el-button style="margin-left: 10px;size: mini;" type="danger">不允许</el-button>
    <p style="margin-left: 60px;margin-top: 4px;">当前状态:</p>
    <div style="margin-top: 4px; margin-left: 10px;">手动</div>
    <el-button style="margin-left: 10px;size: mini;" type="primary">切换</el-button>
    <el-input  placeholder="请输入玻璃id" style="width: 180px;size: mini;margin-left: 60px;"></el-input>
    <el-button style="margin-left: 10px;size: mini;" type="primary">添加</el-button>
    <p style="margin-left: 60px;margin-top: 4px;">玻璃id:</p>
    <el-input  style="width: 180px;size: mini;margin-left: 30px;"></el-input>
  </div>
    <div style="display: flex;">
      <p style="margin-left: 290px;margin-top: 20px;font-weight: bold;">上片位</p>
      <p style="margin-left: 630px;margin-top: 20px;font-weight: bold;">扫码位</p>
  <el-dialog v-model="add" top="10vh" width="70%" :title="$t('searchOrder.addcage')" >
    <div style="margin-bottom: 20px">
      <el-form>
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="4">
              <div id="dt" style="font-size: 15px;">
              <el-form-item :label="$t('searchOrder.tida')"  style="width: 14vw">
                {{ currentRow.deviceId }}
            <!-- <el-input v-model="currentRow.id" autocomplete="off"></el-input> -->
              </el-form-item>
              </div>
          </el-col>
          <el-col :span="5">
            <div id="dta" style="font-size: 15px;">
          <el-form-item :label="$t('searchOrder.gridnumbera')" style="width: 14vw">
                {{ currentRow.slot }}
                <!-- <el-input v-model="currentRow.slot" autocomplete="off"></el-input> -->
              </el-form-item>
              </div>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <div style="display: flex;">
    <div style="margin-top: 20px;">
      <p style="margin-top: 10px;margin-left: 100px;margin-bottom: 20px;">当前信息</p>
      <el-form label-position="right" label-width="90px">
      <el-form-item style="width: 20vw" label="玻璃id:">
      <el-input style="width: 180px" size="mini" placeholder="请输入玻璃id"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="订单编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入订单编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="列表编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入列表编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="箱子编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入箱子编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="长:">
      <el-input style="width: 180px" size="mini" placeholder="请输入长"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="宽:">
      <el-input style="width: 180px" size="mini" placeholder="请输入宽"></el-input>
       </el-form-item>
      </el-form>
      </div>
    <div style="margin-top: 20px;">
      <p style="margin-top: 10px;margin-left: 100px;margin-bottom: 20px;">修改信息</p>
      <el-form label-position="right" label-width="90px">
      <el-form-item style="width: 20vw" label="玻璃id:">
      <el-input style="width: 180px" size="mini" placeholder="请输入玻璃id"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="订单编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入订单编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="列表编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入列表编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="箱子编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入箱子编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="长:">
      <el-input style="width: 180px" size="mini" placeholder="请输入长"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="宽:">
      <el-input style="width: 180px" size="mini" placeholder="请输入宽"></el-input>
       </el-form-item>
      </el-form>
      </div>
    <div style="margin-top: 20px;">
      <p style="margin-top: 10px;margin-left: 100px;margin-bottom: 20px;">修改信息</p>
      <el-form label-position="right" label-width="90px">
      <el-form-item style="width: 20vw" label="玻璃id:">
      <el-input style="width: 180px" size="mini" placeholder="请输入玻璃id"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="订单编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入订单编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="列表编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入列表编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="箱子编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入箱子编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="长:">
      <el-input style="width: 180px" size="mini" placeholder="请输入长"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="宽:">
      <el-input style="width: 180px" size="mini" placeholder="请输入宽"></el-input>
       </el-form-item>
      </el-form>
      </div>
    <div style="margin-top: 20px;">
      <p style="margin-top: 10px;margin-left: 100px;margin-bottom: 20px;">当前信息</p>
      <el-form label-position="right" label-width="90px">
      <el-form-item style="width: 20vw" label="玻璃id:">
      <el-input style="width: 180px" size="mini" placeholder="请输入玻璃id"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="订单编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入订单编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="列表编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入列表编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="箱子编号:">
      <el-input style="width: 180px" size="mini" placeholder="请输入箱子编号"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="长:">
      <el-input style="width: 180px" size="mini" placeholder="请输入长"></el-input>
       </el-form-item>
      <el-form-item style="width: 20vw" label="宽:">
      <el-input style="width: 180px" size="mini" placeholder="请输入宽"></el-input>
       </el-form-item>
      </el-form>
      </div>
      <div style="margin-top: -20px;margin-bottom: 40px;margin-left: 30px">
          <el-input v-model="glassId"   :placeholder="$t('searchOrder.inputid')" clearable style="width: 200px;">
          </el-input>
          <el-button type="primary" plain style="margin-left: 10px;" @click="searchout">{{ $t('searchOrder.search') }}</el-button>
    </div>
        </div>
  <template #footer>
    <div id="dialog-footer">
      <el-button type="primary" @click="dialogFormVisible = false">
        确认
      </el-button>
      <el-button @click="dialogFormVisible = false">取消</el-button>
    </div>
  </template>
</el-dialog>
<el-dialog v-model="dialogFormVisiblea" top="10vh" width="85%" title="理片笼信息" >
  <!-- <el-input  placeholder="请输入工程号" style="width: 180px;size: mini;"></el-input> -->
    <!-- <el-button style="margin-left: 10px;size: mini;" type="primary">查询</el-button> -->
    <el-table  ref="table" style="margin-top: 20px;height: 500px;"
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="id" align="center" label="大理片笼表ID" min-width="80" />
          <el-table-column prop="deviceId" align="center" label="理片笼号" min-width="120" />
          <el-table-column prop="slot" align="center" label="栅格号" min-width="120" />
    <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;max-height: 500px;">
        <el-table height="100%" ref="table"
        :data="tableDataf" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="glassId" align="center" :label="$t('searchOrder.glassID')" min-width="120" />
          <el-table-column prop="sequence" align="center" :label="$t('searchOrder.pieceingrid')" min-width="180" />
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="150" />
          <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="150"/>
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="150"/>
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="150"/>
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="150"/>
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="150"/>
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="150"/>
          <el-table-column
          align="center"
            :label="$t('searchOrder.startstatus')"
            min-width="80"
            prop="state"
          >
          <template #default="scope">
          <el-tag
            :type="scope.row.state === 1 ? 'success' : 'danger'"
          >
          {{ scope.row.state === 1 ? $t('searchOrder.enable') : $t('searchOrder.disable') }}
          </el-tag>
        </template>
          </el-table-column>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="150"/>
          <!-- <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="150"/> -->
          <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center" width="150">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="finisha(scope.row)">{{ $t('searchOrder.sureadd') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
      </div>
  </el-dialog>
<el-dialog v-model="dialogFormVisiblea" top="5vh" width="97%" :title="$t('searchOrder.cageinformation')">
    <el-table
          :data="paginatedUsers"
          @row-click="handleRowClick"
          height="500"
          @expand-change="handleExpandChange"
          row-key="id"
          default-expand-all
          :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
        >
          <el-table-column type="expand">
            <template #default="props">
              <div v-if="props.row.bigStorageCageDetails && props.row.bigStorageCageDetails.length">
                <el-table
                  :data="props.row.bigStorageCageDetails"
                  border
                  style="width: 100%;margin-left: 20px;"
                  row-key="id"
                  :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
                >
          <!-- <el-table-column prop="menuName" label="二级菜单栏" align="center" min-width="140" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"/>   -->
          <el-table-column prop="glassId" :label="$t('searchOrder.glassID')" align="center" min-width="90"/>
          <el-table-column prop="sequence" align="center" :label="$t('searchOrder.pieceingrid')" min-width="110" />
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="120" />
          <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="80" />
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column
            align="center"
            label="启用状态"
            :label="$t('searchOrder.startstatus')"
            min-width="80"
            prop="state"
          >
          <template #default="scope">
        <el-tag :type="getStatusType(scope.row.state)">
          {{ getStatusText(scope.row.state) }}
        </el-tag>
      </template>
          </el-table-column>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="80" />
           <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center"  min-width="220">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="broke(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button size="mini" type="text" plain @click="brokec(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
              <el-button size="mini" type="text"
              :disabled="!((props.row.bigStorageCageDetails[0].state !== 102 && scope.$index == 0 ) || (props.row.bigStorageCageDetails[(scope.$index - 1)<0?0:scope.$index-1].state==102)&&(scope.row.state!=102))"
               plain @click="outfil(scope.row)">
               {{ $t('searchOrder.outfilm') }}
              </el-button>
            </template>
        </el-table-column>
                </el-table>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="id" :label="$t('searchOrder.cagetableID')" align="center" min-width="100"/>
          <el-table-column prop="deviceId" align="center" :label="$t('searchOrder.cagenumber')" min-width="150" />
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="150" />
          <el-table-column
          align="center"
            :label="$t('searchOrder.startstatus')"
            min-width="80"
            prop="enableState"
          >
          <template #default="scope">  
        <el-tag :type="getStatusType(scope.row.enableState)">
          {{ getStatusText(scope.row.enableState) }}
        </el-tag>
      </template>
          <el-tag
            :type="scope.row.enableState === 1 ? 'success' : 'danger'"
            @click="toggleEnableState(scope.row)"
          >
            {{ scope.row.enableState === 1 ? $t('searchOrder.enable') : $t('searchOrder.disable')}}
          </el-tag>
        </template>
          </el-table-column>
          <el-table-column prop="remainWidth" align="center" label="剩余宽度" min-width="120" />
          <el-table-column prop="remainWidth" align="center" :label="$t('searchOrder.remainingwidth')" min-width="120" />
       <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center">
            <template #default="scope">
              <el-button size="mini" type="text" plain  @click="handleBindRack(scope.row)">{{ $t('searchOrder.add') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
        <div id="demo-pagination-block">
    <el-pagination
    style="margin-left: 850px;"
      v-model:current-page="currentPage4"
      v-model:page-size="pageSize4"
      :page-sizes="[100, 200, 300, 400]"
      :small="small"
      :disabled="disabled"
      :background="background"
      layout="total, sizes, prev, pager, next, jumper"
      :total="400"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
        <div>
    <div style="margin-top: 20px; text-align: center;">
      <!-- 上一页按钮 -->
      <el-button @click="prevPage" :disabled="currentPage === 1">{{ $t('searchOrder.up') }}</el-button>
      <!-- 下一页按钮 -->
      <el-button @click="nextPage" :disabled="currentPage >= totalPages">{{ $t('searchOrder.down') }}</el-button>
      <!-- 当前页显示的条数 -->
      <span style="margin-left: 10px;">{{ $t('searchOrder.now') }} {{ itemsPerPage }} {{ $t('searchOrder.tit') }}</span>
    </div>
  </div>
</el-dialog>
<el-dialog v-model="dialogFormVisibleb" top="10vh" width="85%" title="出片队列" >
  <div style="display: flex;">
  </el-dialog>
<!-- </el-dialog> -->
<el-dialog v-model="dialogFormVisibleb" top="5vh" width="85%" :title="$t('searchOrder.productionqueue')">
  <!-- <div style="display: flex;">
  <p style="margin-top: 3px;">队列状态:</p>
  <p style="margin-top: 3px;">开始</p>
    <el-button style="margin-left: 10px;size: mini;" type="danger">停止</el-button>
    <el-button style="margin-left: 10px;size: mini;" type="primary">添加</el-button>
  </div>
  </div> -->
    <el-table  ref="table" style="margin-top: 20px;height: 500px;"
        :data="tableDatab" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="id" fixed align="center" label="钢化小片信息表id" min-width="150"/>
          <!-- <el-table-column prop="glass_id" align="center" label="玻璃id" min-width="120" /> -->
          <el-table-column prop="flowcardId" fixed align="center" label="流程卡" min-width="120" />
          <el-table-column prop="glassType" align="center" label="流程卡玻璃类型" min-width="150" />
          <el-table-column prop="width" align="center" label="宽" min-width="80" />
          <el-table-column prop="height" align="center" label="高" min-width="80" />
          <el-table-column prop="thickness" align="center" label="厚度" min-width="80" />
          <el-table-column prop="filmsid" align="center" label="膜系" min-width="80" />
          <!-- <el-table-column prop="ishorizontal" align="center" label="钢化是否接受横放" min-width="150" /> -->
          <el-table-column prop="id" fixed align="center" :label="$t('searchOrder.sheetID')" min-width="150"/>
          <el-table-column prop="flowcardId" fixed align="center" :label="$t('searchOrder.processcards')" min-width="120" />
          <el-table-column prop="glassType" align="center" :label="$t('searchOrder.processcardtype')" min-width="150" />
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')"  min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="filmsid" align="center" :label="$t('searchOrder.coatingtypes')" min-width="80" />
          <el-table-column
            align="center"
            label="钢化是否接受横放"
            :label="$t('searchOrder.acceptshorizontal')"
            min-width="150"
            prop="ishorizontal"
          >
@@ -591,15 +1124,14 @@
        </el-tag>  
      </template> 
          </el-table-column>
          <el-table-column prop="temperingLayoutId" align="center" label="钢化版图id" min-width="120" />
          <el-table-column prop="temperingFeedSequence" align="center" label="钢化版图片序" min-width="120" />
          <el-table-column prop="xCoordinate" align="center" label="x坐标" min-width="80" />
          <el-table-column prop="yCoordinate" align="center" label="y坐标" min-width="80" />
          <el-table-column prop="angle" align="center" label="旋转角度(逆时针)" min-width="150" />
          <!-- <el-table-column prop="state" align="center" label="状态" min-width="80" /> -->
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="120" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column prop="xCoordinate" align="center" :label="$t('searchOrder.xcoordinates')" min-width="80" />
          <el-table-column prop="yCoordinate" align="center" :label="$t('searchOrder.ycoordinates')" min-width="80" />
          <el-table-column prop="angle" align="center" :label="$t('searchOrder.rotationangle')" min-width="150" />
          <el-table-column
            align="center"
            label="状态"
            :label="$t('searchOrder.state')"
            min-width="80"
            prop="state"
          >
@@ -609,10 +1141,11 @@
        </el-tag>  
      </template> 
          </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="150">
          <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center" width="150">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">添加</el-button>
              <el-button size="mini" type="text" plain @click="handleBindRacka(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain @click="brokea(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button size="mini" type="text" plain @click="brokeb(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button size="mini" type="text" plain @click="deletea(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
@@ -620,7 +1153,6 @@
 
</template>
<style scoped>
#dt { display:block; float:left;line-height: 20px;margin-left: 100px;}
#dta { display:block; float:left;line-height: 20px;margin-left: 80%;}
#dialog-footer{
@@ -719,7 +1251,7 @@
}
 
.img-dlpl{
  margin-left: 200px;
  margin-left: 80px;
  background-image:url('../../assets/dlpl.png');
  background-repeat: no-repeat;
    background-attachment: local;
UI-Project/src/views/StockBasicData/stockBasicData.vue
@@ -11,6 +11,9 @@
// import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
//  import LanguageMixin from './lang/LanguageMixin'
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const tableData = ref([])
const slot = ref('')
@@ -32,17 +35,17 @@
          }
          });
// 破损
 const open = async(row) => {
  try {
 const open = async(row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否破损该条信息?',
      '提示',
      t('workOrder.messagedamaged'),
      t('workOrder.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('workOrder.yes'),
        cancelButtonText: t('workOrder.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/cacheGlass/edgStorageCage/edgReportStatus", {
@@ -64,16 +67,16 @@
};  
// 拿走 
 const opena = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否拿走该条信息?',
      '提示',
      t('workOrder.takemessage'),
      t('workOrder.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('workOrder.yes'),
        cancelButtonText: t('workOrder.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/cacheGlass/edgStorageCage/edgReportStatus", {
@@ -120,17 +123,17 @@
        <el-table height="240" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="GlassId" align="center" label="玻璃id" min-width="180" />
          <el-table-column prop="Height" align="center" label="高" min-width="80" />
          <el-table-column prop="Width" align="center" label="宽" min-width="120" />
          <el-table-column prop="Thickness" align="center" label="厚度" min-width="120" />
          <el-table-column prop="FilmsId" align="center" label="膜系" min-width="120" />
          <el-table-column prop="SerialNumber" align="center" label="出片顺序" min-width="120" />
          <el-table-column prop="FlowCardId" align="center" label="流程卡号" min-width="120" />
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column prop="GlassId" align="center" :label="$t('workOrder.glassID')" min-width="180" />
          <el-table-column prop="Height" align="center" :label="$t('workOrder.height')" min-width="80" />
          <el-table-column prop="Width" align="center" :label="$t('workOrder.width')" min-width="120" />
          <el-table-column prop="Thickness" align="center" :label="$t('workOrder.thickness')" min-width="120" />
          <el-table-column prop="FilmsId" align="center" :label="$t('workOrder.coatingtypes')" min-width="120" />
          <el-table-column prop="SerialNumber" align="center" :label="$t('workOrder.productionsequence')" min-width="120" />
          <el-table-column prop="FlowCardId" align="center" :label="$t('workOrder.cardnumber')" min-width="120" />
          <el-table-column fixed="right" :label="$t('workOrder.operate')" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="open(scope.row)">破损</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">拿走</el-button>
              <el-button size="mini" type="text" plain @click="open(scope.row)">{{ $t('workOrder.breakage') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('workOrder.takeout') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
UI-Project/src/views/StockBasicData/stockBasicDatatwo.vue
@@ -11,6 +11,9 @@
// import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
//  import LanguageMixin from './lang/LanguageMixin'
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const tableData = ref([])
const slot = ref('')
@@ -33,16 +36,16 @@
          });
// 破损
 const open = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否破损该条信息?',
      '提示',
      t('workOrder.messagedamaged'),
      t('workOrder.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('workOrder.yes'),
        cancelButtonText: t('workOrder.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/cacheGlass/edgStorageCage/edgReportStatus", {
@@ -64,16 +67,16 @@
};  
// 拿走 
 const opena = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否拿走该条信息?',
      '提示',
      t('workOrder.takemessage'),
      t('workOrder.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('workOrder.yes'),
        cancelButtonText: t('workOrder.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/cacheGlass/edgStorageCage/edgReportStatus", {
@@ -121,17 +124,17 @@
        <el-table height="240" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="GlassId" align="center" label="玻璃id" min-width="180" />
          <el-table-column prop="Height" align="center" label="高" min-width="80" />
          <el-table-column prop="Width" align="center" label="宽" min-width="120" />
          <el-table-column prop="Thickness" align="center" label="厚度" min-width="120" />
          <el-table-column prop="FilmsId" align="center" label="膜系" min-width="120" />
          <el-table-column prop="SerialNumber" align="center" label="出片顺序" min-width="120" />
          <el-table-column prop="FlowCardId" align="center" label="流程卡号" min-width="120" />
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column prop="GlassId" align="center" :label="$t('workOrder.glassID')" min-width="180" />
          <el-table-column prop="Height" align="center" :label="$t('workOrder.height')" min-width="80" />
          <el-table-column prop="Width" align="center" :label="$t('workOrder.width')" min-width="120" />
          <el-table-column prop="Thickness" align="center" :label="$t('workOrder.thickness')" min-width="120" />
          <el-table-column prop="FilmsId" align="center" :label="$t('workOrder.coatingtypes')" min-width="120" />
          <el-table-column prop="SerialNumber" align="center" :label="$t('workOrder.productionsequence')" min-width="120" />
          <el-table-column prop="FlowCardId" align="center" :label="$t('workOrder.cardnumber')" min-width="120" />
          <el-table-column fixed="right" :label="$t('workOrder.operate')" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="open(scope.row)">破损</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">拿走</el-button>
              <el-button size="mini" type="text" plain @click="open(scope.row)">{{ $t('workOrder.breakage') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('workOrder.takeout') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
UI-Project/src/views/UnLoadGlass/Landingindication.vue
@@ -22,7 +22,7 @@
              :height="rack.item.height" 
              :fill="rack.item.fillColor"
            />
            <text :x="rack.x + rack.width / 2" :y="rack.y - 10" text-anchor="middle">{{ index + 1 }}号工位</text>
            <text :x="rack.x + rack.width / 2" :y="rack.y - 10" text-anchor="middle">{{ index + 1 }}{{ $t('reportWork.workstation') }}</text>
            <text :x="rack.x + rack.width / 2" :y="rack.y + rack.height + 20" text-anchor="middle">{{ rack.item.content }}</text>
          </g>
        </g>
@@ -34,6 +34,9 @@
<script  setup>
import { ref, watchEffect ,onMounted} from 'vue';
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
import Swal from 'sweetalert2'
import request from "@/utils/request";
import { initializeWebSocket } from '@/utils/WebSocketService';
@@ -43,7 +46,7 @@
 
  { x: 280, y: 100, height: 100, width: 60, fillColor: '#6a6da9', item: { height: 90, width: 10, fillColor: 'yellow', content: 'NG12345678',downGlassInfoList:"" } },
 
  { x: 140, y: 420, height: 60, width: 110, fillColor: '#6a6da9', item: { height: 20, width: 100, fillColor: 'yellow', content: 'NG1234561454' ,downGlassInfoList:""} }
  { x: 140, y: 320, height: 60, width: 110, fillColor: '#6a6da9', item: { height: 20, width: 100, fillColor: 'yellow', content: 'NG1234561454' ,downGlassInfoList:""} }
  
]);
@@ -167,7 +170,8 @@
  tableContent += '</table>';
  Swal.fire({
    title: '玻璃信息',
    // title: '玻璃信息',
    title: "$t('reportWork.glassinformation')",
    html: tableContent,
    customClass: {
      popup: 'format-pre'
@@ -196,7 +200,7 @@
.glass-rack {
  margin-left: 20px;
  width: 500px;
  margin-top: 10px;
  margin-top: 5px;
}
.rack-rect:hover {
  cursor: pointer;
UI-Project/src/views/UnLoadGlass/Landingindicationtwo.vue
@@ -22,7 +22,7 @@
              :height="rack.item.height" 
              :fill="rack.item.fillColor"
            />
            <text :x="rack.x + rack.width / 2" :y="rack.y - 10" text-anchor="middle">{{ index + 4 }}号工位</text>
            <text :x="rack.x + rack.width / 2" :y="rack.y - 10" text-anchor="middle">{{ index + 4 }}{{ $t('reportWork.workstation') }}</text>
            <text :x="rack.x + rack.width / 2" :y="rack.y + rack.height + 20" text-anchor="middle">{{ rack.item.content }}</text>
          </g>
        </g>
@@ -34,6 +34,9 @@
<script setup>
import { ref, watchEffect ,onMounted} from 'vue';
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
import Swal from 'sweetalert2'
import request from "@/utils/request";
import { initializeWebSocket } from '@/utils/WebSocketService';
@@ -43,7 +46,7 @@
 
  { x: 280, y: 100, height: 100, width: 60, fillColor: '#6a6da9', item: { height: 90, width: 10, fillColor: 'yellow', content: 'NG12345678' } },
 
  { x: 140, y: 420, height: 60, width: 110, fillColor: '#6a6da9', item: { height: 20, width: 100, fillColor: 'yellow', content: 'NG1234561454' } }
  { x: 140, y: 320, height: 60, width: 110, fillColor: '#6a6da9', item: { height: 20, width: 100, fillColor: 'yellow', content: 'NG1234561454' } }
  
]);
@@ -164,7 +167,8 @@
  tableContent += '</table>';
  Swal.fire({
    title: '玻璃信息',
    title: "$t('reportWork.glassinformation')",
    // title: '玻璃信息',
    html: tableContent,
    customClass: {
      popup: 'format-pre'
UI-Project/src/views/UnLoadGlass/loadmachinerack.vue
@@ -5,6 +5,9 @@
import {useRouter} from "vue-router"
const router = useRouter()
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import Landingindication from "./Landingindication.vue";
@@ -24,7 +27,7 @@
// 表单数据
const workstationId = ref('');
const flowCardId = ref('');
const flowCardOptions = ref([]);
const flowCardOptions = ref('[]');
const tableData = reactive([]);
// 方法
const handleSelectionChange = () => {
@@ -44,9 +47,9 @@
    const response = await request.get('unLoadGlass/downWorkStation/getflowCardId');
    console.log(response)
    if (response.code === 200) {
  flowCardOptions.value = response.data
    .filter(item => item !== null)
    .map(item => ({ flowcard_id: item.flow_card_Id }));
  flowCardOptions.value = response.data.filter(item => item !== null)
.map(item => ({ flowcard_id: item.flow_card_id }));
  console.log(flowCardOptions.value);
}
 else {
@@ -187,30 +190,27 @@
        <el-table height="100%" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="workstationId" align="center" label="下片位" min-width="80" />
          <el-table-column prop="workstationId" align="center" label="架号" min-width="120" />
          <el-table-column prop="flowCardId" align="center" label="流程卡号" min-width="120" />
          <el-table-column prop="totalquantity" align="center" label="总数量" min-width="120" />
          <el-table-column prop="racksnumber" align="center" label="已落架数量" min-width="120" />
          <el-table-column prop="work_state" align="center" label="状态" min-width="120" />
          <el-table-column prop="deviceId" align="center" label="设备号" min-width="120" />
          <el-table-column prop="workstationId" align="center" :label="$t('reportWork.lowerbit')" min-width="80" />
          <el-table-column prop="workstationId" align="center" :label="$t('reportWork.shelfnumber')" min-width="120" />
          <el-table-column prop="flowCardId" align="center" :label="$t('reportWork.cardnumber')" min-width="120" />
          <el-table-column prop="totalquantity" align="center" :label="$t('reportWork.totalquantity')" min-width="120" />
          <el-table-column prop="racksnumber" align="center" :label="$t('reportWork.beendropped')" min-width="120" />
          <el-table-column prop="work_state" align="center" :label="$t('reportWork.state')" min-width="120" />
          <el-table-column prop="deviceId" align="center" :label="$t('reportWork.devicenumber')" min-width="120" />
          <el-table-column
            align="center"
            label="启用状态"
            :label="$t('reportWork.startstatus')"
            min-width="80"
            prop="enableState"
          >
          <template #default="scope">
            <el-tag type="success" >{{ scope.row.enableState==1?"启用":"未启用"  }}</el-tag>
            <el-tag type="success" >{{ scope.row.enableState==1? $t('reportWork.enable') : $t('reportWork.unenable')}}</el-tag>
          </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column fixed="right" :label="$t('reportWork.operate')" align="center" width="200">
            <template #default="scope">
            <el-button size="mini" type="text" plain v-show="scope.row.enableState !== '已启用' " @click="handleBindRack(scope.row)">绑定架子</el-button>
            <el-button size="mini" type="text" plain  @click="handleBindRack2(scope.row)">清空</el-button>
            <el-button size="mini" type="text" plain v-show="scope.row.enableState !== '已启用' " @click="handleBindRack(scope.row)">{{ $t('reportWork.bindingshelves') }}</el-button>
            <el-button size="mini" type="text" plain  @click="handleBindRack2(scope.row)">{{ $t('reportWork.clear') }}</el-button>
          </template>
        </el-table-column>
        </el-table>
@@ -218,15 +218,15 @@
    </el-card>
    <el-dialog v-model="dialogFormVisiblea" top="21vh" width="30%" title="绑定架子" >
    <el-dialog v-model="dialogFormVisiblea" top="21vh" width="40%" :title="$t('reportWork.bindingshelves')">
    <div style="margin-left: 50px;margin-top: 10px;margin-bottom: 10px;">
      <el-form  size="mini" label-width="150px">
        <el-form  label-width="100px" label-position="right">
          <el-form-item label="架号:" :required="true" style="width: 18vw">
      <el-form  size="mini" label-width="100px">
        <el-form  label-width="210px" label-position="right">
          <el-form-item :label="$t('reportWork.shelfnumbera')" :required="true" style="width: 25vw">
            <el-input v-model="workstationId" autocomplete="off"/>
          </el-form-item>
          <el-form-item label="流程卡号:" :required="true" style="width: 18vw;">
          <el-select v-model="flowCardId" placeholder="请选择流程卡号">
          <el-form-item :label="$t('reportWork.cardnumbera')" :required="true" style="width: 25vw;">
          <el-select v-model="flowCardId" :placeholder="$t('reportWork.incardnumber')">
            <el-option v-for="item in flowCardOptions" :key="item.flowcard_id" :label="item.flowcard_id" :value="item.flowcard_id" />
          </el-select>
        </el-form-item>
@@ -236,9 +236,9 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleConfirm">
          确认
          {{ $t('reportWork.sure') }}
        </el-button>
        <el-button @click="dialogFormVisiblea = false">取消</el-button>
        <el-button @click="dialogFormVisiblea = false">{{ $t('reportWork.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
@@ -246,14 +246,14 @@
  <el-dialog v-model="dialogFormVisiblea2" top="21vh" width="30%" title="清除架子玻璃" >
  <el-dialog v-model="dialogFormVisiblea2" top="21vh" width="30%" :title="$t('reportWork.clearglass')">
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="handleclear">
          确认
          {{ $t('reportWork.sure') }}
        </el-button>
        <el-button @click="dialogFormVisiblea2 = false">取消</el-button>
        <el-button @click="dialogFormVisiblea2 = false">{{ $t('reportWork.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
UI-Project/src/views/User/permissions.vue
@@ -5,8 +5,12 @@
const router = useRouter()
const add = ref(false)
const adda = ref(false)
const addc = ref(false)
const addb = ref(false)
const editingUser = ref({}); // 用于存储当前编辑的用户数据
import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
import request from "@/utils/request"
import { ref, onMounted } from "vue";
// import { ref } from 'vue'
@@ -15,8 +19,9 @@
const selectedProjectNoa = ref(''); // 当前选中的角色 
// const options = ref<any[]>([]); // 下拉选项列表  
  const menuName = ref('');
  const parentId = ref('');
  const listSort = ref('');
  const url = ref('');
const currentRow = reactive({}); // 当前行的数据
const tableData = ref([])
const slot = ref('')
 request.get("/loadGlass/sys/menu/nav").then((res) => {
@@ -50,7 +55,7 @@
    const response = await request.post('/loadGlass/sys/role/queryRole',{
  key: ''
});  
    if (response.code == 200) {
    if (response.code === 200) {
    titleSelectJsona.value.processTypea = response.data;
    console.log(response.data);
 
@@ -61,20 +66,64 @@
    console.error('Error fetching options:', error);  
  }  
}; 
// 添加
const handleBindRack = (row) => {
  // selectedRow.value = row; // 更新选中的行数据
  currentRow.menuName  = row.menuName; // 直接设置响应式属性
  currentRow.id  = row.id; // 直接设置响应式属性
  // currentRow.slot = row.slot;
  // window.localStorage.setItem('deviceId', row.deviceId)
  // window.localStorage.setItem('slot', row.slot)
  addb.value = true; // 打开绑定架子对话框
};
// 添加一级菜单
const getTableRow = async () => {
  try {
    const response = await request.post('/loadGlass/sys/menu/save', {
      menuName: menuName.value,
      parentId: parentId.value,
      listSort: listSort.value,
      url: url.value,
    }); 
 
    if (response.code == 200) {
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      add.value = false;
    //  tableData.value = response.data;
     tableData.value = response.data;
       menuName.value = '';
       listSort.value = '';
       url.value = '';
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
    }
  } catch (error) {
    // 处理错误
    console.error(error);
  }
};
// 添加二级菜单
const getTableRowb = async () => {
  try {
    const dataToSend = {
      parentId: currentRow.id,
      // menuName: currentRow.menuName,
      // children: [
      //   {
      menuName: menuName.value,
      listSort: listSort.value,
      url: url.value,
      //   }
      // ]
    };
    const response = await request.post('/loadGlass/sys/menu/save',dataToSend );
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      addb.value = false;
     tableData.value = response.data;
       menuName.value = '';
       listSort.value = '';
       url.value = '';
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
@@ -86,24 +135,60 @@
};
// 处理编辑按钮点击  
function handleEdit(row) {  
  editingUser.value = { ...row }; // 使用展开运算符复制当前行数据
  listSort.value = row.listSort;
  menuName.value = row.menuName;
  url.value = row.url;
  adda.value = true; // 显示对话框  
}
// 修改二级菜单
function handleEditc(row) {
  listSort.value = row.listSort;
  menuName.value = row.menuName;
  url.value = row.url;
  addc.value = true; // 显示对话框
}  
// 编辑
const getTableRowa = async () => {
  try {
    const response = await request.post('/loadGlass/sys/menu/updateMenu', {
      parentId: currentRow.id,
      menuName: menuName.value,
      parentId: parentId.value,
      listSort: listSort.value,
      url: url.value,
    }); 
    if (response.code == 200) {
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      editingUser.value = {};
      adda.value = false;
     tableData.value = response.data;
       menuName.value = '';
       listSort.value = '';
       url.value = '';
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
    }
  } catch (error) {
    // 处理错误
    console.error(error);
  }
};
// 编辑二级菜单
const getTableRowac = async () => {
  try {
    const response = await request.post('/loadGlass/sys/menu/updateMenu', {
      menuName: menuName.value,
      listSort: listSort.value,
      url: url.value,
    });
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      addc.value = false;
     tableData.value = response.data;
       menuName.value = '';
       listSort.value = '';
       url.value = '';
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
@@ -115,16 +200,16 @@
};
// 删除 
 const opena = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否删除该用户?',
      '提示',
      t('customer.demenu'),
      t('customer.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('customer.yes'),
        cancelButtonText: t('customer.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/loadGlass/sys/menu/deleteMenu", {
@@ -144,54 +229,16 @@
  }  
};   
// const gridOptions = reactive({
//   border:  "full",//表格加边框
//   keepSource: true,//保持源数据
//   align: 'center',//文字居中
//   stripe:true,//斑马纹
//   rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮
//   id: 'OrderList',
//   showFooter: true,//显示脚
//   printConfig: {},
//   importConfig: {},
//   exportConfig: {},
//   scrollY:{ enabled: true },//开启虚拟滚动
//   showOverflow:true,
//   columnConfig: {
//     resizable: true,
//     useKey: true
//   },
//   filterConfig: {   //筛选配置项
//     remote: true
//   },
//   customConfig: {
//     storage: true
//   },
//   editConfig: {
//     trigger: 'click',
//     mode: 'row',
//     showStatus: true
//   },
//   data:  [
//     {
//       'id': '1',
//       'long': '5',
//       'wide': '1005',
//       'thick': '183.6',
//     }
//   ]
// })
</script>
<template>
  <div style="height: 700px;">
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">添加菜单</el-button>
  <div style="height: 600px;">
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">{{ $t('customer.addmenu') }}</el-button>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;max-height: 650px;">
              <el-table  
          :data="tableData" 
          height="650"
          height="550"
          @expand-change="handleExpandChange"  
          row-key="id" 
          :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}" 
@@ -206,61 +253,43 @@
                  row-key="id"  
                  :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}" 
                >  
                  <el-table-column prop="menuName" label="二级菜单栏" align="center" min-width="140" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"/>
                  <el-table-column prop="url" label="链接" align="center" min-width="160"/>
          <el-table-column prop="id" align="center" label="排序" min-width="140"/>
                  <el-table-column fixed="right" label="操作" align="center">
                  <el-table-column prop="menuName" :label="$t('customer.semenu')" align="center" min-width="140" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"/>
                  <el-table-column prop="url" :label="$t('customer.link')" align="center" min-width="160"/>
          <el-table-column prop="listSort" align="center" :label="$t('customer.sort')" min-width="140"/>
                  <el-table-column fixed="right" :label="$t('customer.operate')" align="center">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain @click="handleEditc(scope.row)">{{ $t('customer.exit') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('customer.delete') }}</el-button>
            </template>
        </el-table-column>
                </el-table>  
              </div>  
            </template>  
          </el-table-column>  
          <el-table-column prop="menuName" label="一级菜单栏" align="center" min-width="120"  />
                  <el-table-column prop="url" label="链接" align="center" min-width="200"/>
          <el-table-column prop="id" align="center" label="排序" min-width="180" />
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column prop="menuName" :label="$t('customer.firstmenu')" align="center" min-width="120"  />
                  <el-table-column prop="url" :label="$t('customer.link')" align="center" min-width="200"/>
          <el-table-column prop="listSort" align="center" :label="$t('customer.sort')" min-width="180" />
          <el-table-column fixed="right" :label="$t('customer.operate')" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain @click="handleBindRack(scope.row)">{{ $t('customer.addmenua') }}</el-button>
              <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">{{ $t('customer.exit') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('customer.delete') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
       <!-- <el-table height="240" ref="table"
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="menuName" align="center" label="菜单栏" min-width="180" />
          <el-table-column align="center" label="链接" min-width="180">
            <template #default="scope">
             <el-tag v-for="role in scope.row.children">
            {{role.url}}
           </el-tag>
         </template>
            </el-table-column>
          <el-table-column prop="id" align="center" label="排序" min-width="180" />
          <el-table-column fixed="right" label="操作" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="adda = true">编辑</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button>
            </template>
        </el-table-column>
        </el-table> -->
        </el-table>
      </div>
    </el-card>
  </div>
  <el-dialog v-model="add" top="23vh" width="37%" title="添加菜单" >
  <el-dialog v-model="add" top="23vh" width="37%" :title="$t('customer.addmenu')">
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form  size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
      <el-form label-width="150px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div> 
          <el-form-item label="菜单栏:" :required="true" style="width: 25vw">
                <el-input v-model="menuName" autocomplete="off" />
          <el-form-item :label="$t('customer.firstmenuname')" :required="true" style="width: 25vw">
                <el-input v-model="menuName" autocomplete="off" :placeholder="$t('customer.inmenu')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -268,8 +297,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="链接:" :required="true" style="width: 25vw">
                <el-input v-model="url" autocomplete="off" />
          <el-form-item :label="$t('customer.linka')" :required="true" style="width: 25vw">
                <el-input v-model="url" autocomplete="off" :placeholder="$t('customer.inlink')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -277,8 +306,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="排序:" :required="true" style="width: 25vw">
                <el-input v-model="parentId" autocomplete="off" />
          <el-form-item :label="$t('customer.sorta')" :required="true" style="width: 25vw">
                <el-input v-model="listSort" autocomplete="off" :placeholder="$t('customer.insort')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -288,22 +317,79 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRow">
          确认
          {{ $t('customer.sure') }}
        </el-button>
        <el-button @click="add = false">取消</el-button>
        <el-button @click="add = false">{{ $t('customer.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
  <el-dialog v-model="adda" top="23vh" width="37%" title="修改菜单" >
  <el-dialog v-model="addb" top="23vh" width="37%" :title="$t('customer.addmenua')">
    <div style="margin-bottom: 20px">
      <el-form>
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
              <el-form-item :label="$t('customer.firstmenuname')"  style="width: 22vw">
                <!-- {{ currentRow.menuName }} -->
            <el-input disabled v-model="currentRow.menuName" autocomplete="off"></el-input>
              </el-form-item>
              </div>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
     <el-form  :model="editingUser" ref="formRef" size="mini" label-width="150px">
            <el-form  size="mini" label-width="150px">
      <el-form label-width="150px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.semenuname')" :required="true" style="width: 25vw">
                <el-input v-model="menuName" autocomplete="off" :placeholder="$t('customer.inmenu')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.linka')" :required="true" style="width: 25vw">
                <el-input v-model="url" autocomplete="off" :placeholder="$t('customer.inlink')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.sorta')" :required="true" style="width: 25vw">
                <el-input v-model="listSort" autocomplete="off" :placeholder="$t('customer.insort')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        </el-form>
            </el-form>
          </div>
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRowb">
          {{ $t('customer.sure') }}
        </el-button>
        <el-button @click="addb = false">{{ $t('customer.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="adda" top="23vh" width="37%" :title="$t('customer.exmene')">
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
     <el-form ref="formRef" size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div> 
          <el-form-item label="菜单栏:" :required="true" style="width: 25vw">
                <el-input v-model="editingUser.menuName" autocomplete="off" />
          <el-form-item :label="$t('customer.menu')" :required="true" style="width: 25vw">
                <el-input v-model="menuName" autocomplete="off" :placeholder="$t('customer.inmenu')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -311,8 +397,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="链接:" :required="true" style="width: 25vw">
                <el-input v-model="editingUser.url" autocomplete="off" />
          <el-form-item :label="$t('customer.linka')" :required="true" style="width: 25vw">
                <el-input v-model="url" autocomplete="off" :placeholder="$t('customer.inlink')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -320,8 +406,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="排序:" :required="true" style="width: 25vw">
                <el-input v-model="editingUser.parentId" autocomplete="off" />
          <el-form-item :label="$t('customer.sorta')" :required="true" style="width: 25vw">
                <el-input v-model="listSort" autocomplete="off" :placeholder="$t('customer.insort')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -331,9 +417,52 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRowa">
          确认
          {{ $t('customer.sure') }}
        </el-button>
        <el-button @click="adda = false">取消</el-button>
        <el-button @click="adda = false">{{ $t('customer.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog>
  <el-dialog v-model="addc" top="23vh" width="37%" :title="$t('customer.exmenea')">
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
     <el-form ref="formRef" size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.menu')" :required="true" style="width: 25vw">
                <el-input v-model="menuName" autocomplete="off" :placeholder="$t('customer.inmenu')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.linka')" :required="true" style="width: 25vw">
                <el-input v-model="url" autocomplete="off" :placeholder="$t('customer.inlink')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item :label="$t('customer.sorta')" :required="true" style="width: 25vw">
                <el-input v-model="listSort" autocomplete="off" :placeholder="$t('customer.insort')"/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        </el-form>
            </el-form>
          </div>
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRowac">
          {{ $t('customer.sure') }}
        </el-button>
        <el-button @click="addc = false">{{ $t('customer.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
UI-Project/src/views/User/rolelist.vue
@@ -2,10 +2,12 @@
import {Search} from "@element-plus/icons-vue";
import {reactive} from "vue";
import {useRouter} from "vue-router"
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
const router = useRouter()
const add = ref(false)
const adda = ref(false)
const editingUser = ref({}); // 用于存储当前编辑的用户数据
import request from "@/utils/request"
import { ref, onMounted } from "vue";
// import { ref } from 'vue'
@@ -14,35 +16,34 @@
const selectedProjectNoa = ref(''); // 当前选中的角色 
// const options = ref<any[]>([]); // 下拉选项列表  
  const name = ref('');
const tableData = ref([])
const options = ref([])
const selectedOptions = ref([])
// 定义级联选择器的属性
const cascaderProps = {
  value: 'id',
  label: 'menuName',
  multiple: true
};
const slot = ref('')
const titleSelectJsona = ref({
  processType: [],
 
})
// const handleInputChangea = async (value: string) => {
//   if (value) {
//     await fetchOptionsa(value);
//   } else {
//     options.value = []; // 清空选项列表
//   }
// };
onMounted(() => {  
  // 在组件挂载后调用 fetchOptions('') 来加载初始数据(如果需要)
  fetchOptionsa('');  
}); 
  // 角色下拉选  
  const fetchOptionsa = async () => {  
  try {  
    // 发送请求到后端接口
    const response = await request.post('/loadGlass/sys/role/queryRole',{
  key: ''
});  
    if (response.code == 200) {  
     tableData.value = response.data
    // titleSelectJsona.value.processTypea = response.data.menuList;
    // options.value = response.data.menuList
    console.log(response.data);
 
    } else {  
@@ -54,47 +55,94 @@
}; 
// 添加 
const getTableRow = async () => {
  try {
    const response = await request.post('/loadGlass/sys/role/saveRole', {
  try {
    let menuList = [];
    selectedOptions.value.forEach(array => {
      if (array.length >= 2) {
        let id = array[0];
        let parentId = array[1];
        menuList.push({
          id: id,
          parentId: 0,
          children: [
        {
          id: parentId,
          parentId: id,
        }
      ],
        });
      }
    });
    const dataToSend = {
      name: name.value,
    });
      menuList: menuList
    };
    const response = await request.post('/loadGlass/sys/role/saveRole', dataToSend);
    if (response.code == 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      add.value = false;
    //  tableData.value = response.data;
      name.value = '';
      selectedOptions.value = '';
      fetchOptionsa();
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
      ElMessage.error(response.message);
    }
  } catch (error) {
    // 处理错误
    console.error(error);
  }
};
// 处理编辑按钮点击  
function handleEdit(row) {  
  editingUser.value = { ...row }; // 使用展开运算符复制当前行数据
  adda.value = true; // 显示对话框
  name.value = row.name;
  selectedOptions.value = row.selectedOptions
//  options.value = res.data.tree
 adda.value = true; // 显示对话框
  window.localStorage.setItem('id', row.id)
}
// 编辑
const getTableRowa = async () => {
  try {
    const response = await request.post('/loadGlass/sys/role/updateRole', {
  let id = window.localStorage.getItem('id')
  try {
    let menuList = [];
    selectedOptions.value.forEach(array => {
      if (array.length >= 2) {
        let id = array[0];
        let parentId = array[1];
        menuList.push({
          id: id,
          parentId: 0,
          children: [
        {
          id: parentId,
          parentId: id,
        }
      ],
        });
      }
    });
    const dataToSend = {
      id:id,
      name: name.value,
    });
      menuList: menuList
    };
    const response = await request.post('/loadGlass/sys/role/updateRole', dataToSend);
  // try {
  //   const response = await request.post('/loadGlass/sys/role/updateRole', {
  //     id: id,
  //     name: name.value,
  //   });
 
    if (response.code == 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      editingUser.value = {};
      adda.value = false;
     tableData.value = response.data;
      name.value = '';
       selectedOptions.value = '';
      fetchOptionsa()
      tableData.value = response.data;
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
      ElMessage.error(response.message);
    }
  } catch (error) {
    // 处理错误
@@ -103,26 +151,25 @@
};
// 删除 
 const opena = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否删除该用户?',
      '提示',
      t('delivery.derole'),
      t('delivery.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('delivery.yes'),
        cancelButtonText: t('delivery.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/loadGlass/sys/role/delete", {
        ids: row.id,
    })
      const response = await request.post("/loadGlass/sys/role/delete",[row.id])
    if (response.code === 200) {
      ElMessage.success(response.message);
      fetchOptionsa()
      } else {  
        // 删除失败,您可以处理错误或显示错误信息给用户  
      ElMessage.error(response.msg);
      ElMessage.error(response.message);
        // alert('删除失败:' + deleteResponse.message); 
      }  
    }  
@@ -130,77 +177,62 @@
    // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等  
    console.error('发生错误:', error);  
  }  
};
const gridOptions = reactive({
  border:  "full",//表格加边框
  keepSource: true,//保持源数据
  align: 'center',//文字居中
  stripe:true,//斑马纹
  rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮
  id: 'OrderList',
  showFooter: true,//显示脚
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  scrollY:{ enabled: true },//开启虚拟滚动
  showOverflow:true,
  columnConfig: {
    resizable: true,
    useKey: true
  },
  filterConfig: {   //筛选配置项
    remote: true
  },
  customConfig: {
    storage: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'row',
    showStatus: true
  },
  data:  [
    {
      'id': '1',
      'long': '5',
      'wide': '1005',
      'thick': '183.6',
    }
  ]
})
};
request.get("/loadGlass/sys/menu/nav").then((res) => {
 if (res.code == 200) {
 console.log(res.data);
 options.value = res.data.tree
 console.log( options.value);
 } else {
 ElMessage.warning(res.msg)
 }
 });
</script>
<template>
  <div>
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">添加角色</el-button>
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">{{ $t('delivery.addrole') }}</el-button>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;">
        <el-table height="240" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="name" align="center" label="角色" min-width="180" />
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column prop="name" align="center" :label="$t('delivery.role')" min-width="180" />
          <el-table-column fixed="right" :label="$t('delivery.operate')" align="center" width="200">
            <template #default="scope">
              <el-button size="mini" type="text" plain  @click="handleEdit(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain  @click="handleEdit(scope.row)">{{ $t('delivery.edit') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('delivery.delete') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
  <el-dialog v-model="add" top="23vh" width="37%" title="添加角色" >
  <el-dialog v-model="add" top="23vh" width="37%" :title="$t('productStock.addusername')" >
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form  size="mini" label-width="150px">
            <el-form ref="formRef" size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="角色:" :required="true" style="width: 25vw">
                <el-input v-model="name" autocomplete="off" />
          <el-form-item :label="$t('delivery.rolea')" :required="true" style="width: 25vw">
                <el-input :placeholder="$t('delivery.inrole')" v-model="name" autocomplete="off" />
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item :label="$t('delivery.choice')" :required="true" style="width: 25vw;">
        <el-cascader
         v-model="selectedOptions"
         :placeholder="$t('delivery.inchoice')"
         :props="cascaderProps"
         :options="options"
               style="width: 330px"
               clearable />
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -210,22 +242,37 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRow">
          确认
          {{ $t('delivery.sure') }}
        </el-button>
        <el-button @click="add = false">取消</el-button>
        <el-button @click="add = false"> {{ $t('delivery.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
  <el-dialog v-model="adda" top="23vh" width="37%" title="修改角色" >
  <el-dialog v-model="adda" top="23vh" width="37%" :title="$t('delivery.editrole')">
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form :model="editingUser" ref="formRef" size="mini" label-width="150px">
            <el-form ref="formRef" size="mini" label-width="150px">
              <el-form label-width="100px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="角色:" :required="true" style="width: 25vw">
                <el-input v-model="editingUser.name" autocomplete="off" />
          <el-form-item :label="$t('delivery.rolea')" :required="true" style="width: 25vw">
                <el-input :placeholder="$t('delivery.inrole')" v-model="name" autocomplete="off" />
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
       <el-form-item :label="$t('delivery.choice')" :required="true" style="width: 25vw;">
        <el-cascader
         v-model="selectedOptions"
         :placeholder="$t('delivery.inchoice')"
         :props="cascaderProps"
         :options="options"
               style="width: 330px"
               clearable />
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -235,9 +282,9 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRowa">
          确认
          {{ $t('delivery.sure') }}
        </el-button>
        <el-button @click="adda = false">取消</el-button>
        <el-button @click="adda = false">{{ $t('delivery.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
UI-Project/src/views/User/userlist.vue
@@ -5,11 +5,13 @@
const router = useRouter()
const add = ref(false)
const adda = ref(false)
const editingUser = ref({}); // 用于存储当前编辑的用户数据
import request from "@/utils/request"
import { ref, onMounted } from "vue";
// import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
  import { useI18n } from 'vue-i18n'
  const { t } = useI18n()
  let language = ref(localStorage.getItem('lang') || 'zh')
//  import LanguageMixin from './lang/LanguageMixin'
const selectedProjectNoa = ref(''); // 当前选中的角色 
// const options = ref<any[]>([]); // 下拉选项列表  
@@ -31,16 +33,16 @@
          });
// 重置密码
 const open = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否重置用户密码?',
      '提示',
      t('productStock.repassword'),
      t('productStock.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('productStock.yes'),
        cancelButtonText: t('productStock.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      var url="/loadGlass/sys/user/resetPassword?userId="+row.id;
@@ -83,7 +85,7 @@
    const response = await request.post('/loadGlass/sys/role/queryRole',{
  key: ''
});  
    if (response.code == 200) {
    if (response.code === 200) {
    titleSelectJsona.value.processTypea = response.data;
    console.log(response.data);
 
@@ -96,23 +98,33 @@
}; 
// 处理编辑按钮点击  
function handleEdit(row) {  
  editingUser.value = { ...row }; // 使用展开运算符复制当前行数据
  userName.value = row.userName;
  adda.value = true; // 显示对话框  
  window.localStorage.setItem('id', row.id)
// 添加 
const getTableRow = async () => {
  try {
    const response = await request.post('/loadGlass/sys/user/saveUser', {
      userName: userName.value,
      nickName: userName.value,
      password: password.value,
      name: selectedProjectNoa.value,
      roleList: [
    {
      id: selectedProjectNoa.value,
      // name: selectedProjectNoa.value.name,
    }]
      // roleList: selectedProjectNoa.value.map(item => ({
      //   id: item.id,
      //   name: item.name
      // }))
    }); 
    if (response.code == 200) {
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      add.value = false;
    //  tableData.value = response.data;
     tableData.value = response.data;
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
@@ -124,22 +136,26 @@
};
// 编辑
const getTableRowa = async () => {
  let id = window.localStorage.getItem('id')
  try {
    const response = await request.post('/loadGlass/sys/user/updateUser', {
      id: id,
      userName: userName.value,
      password: password.value,
      name: selectedProjectNoa.value,
    });
    if (response.code == 200) {
      roleList: [
    {
      id: selectedProjectNoa.value,
      // roleKey: selectedProjectNoa.value.id,
    }]
  }
  );
    if (response.code === 200) {
      // 绑定成功,处理逻辑
      ElMessage.success(response.message);
      editingUser.value = {};
      adda.value = false;
     tableData.value = response.data;
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
      ElMessage.error(response.message);
    }
  } catch (error) {
    // 处理错误
@@ -148,21 +164,19 @@
};
// 删除 
 const opena = async(row) => {  
  try {
  try {
    const confirmResult = await ElMessageBox.confirm(  
      '是否删除该用户?',
      '提示',
      t('productStock.deusername'),
      t('productStock.prompt'),
      {  
        confirmButtonText: '是',
        cancelButtonText: '取消',
        confirmButtonText: t('productStock.yes'),
        cancelButtonText: t('productStock.cancel'),
        type: 'warning',  
      }
    );
      }
    );
    if (confirmResult === 'confirm') {  
      // 用户点击了“是”,现在调用删除接口  
      const response = await request.post("/loadGlass/sys/user/deleteUser", {
        ids: [row.id],
    })
      const response = await request.post("/loadGlass/sys/user/deleteUser",  [row.id])
    if (response.code === 200) {
      ElMessage.success(response.message);
      } else {  
@@ -177,74 +191,36 @@
  }  
};   
const gridOptions = reactive({
  border:  "full",//表格加边框
  keepSource: true,//保持源数据
  align: 'center',//文字居中
  stripe:true,//斑马纹
  rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮
  id: 'OrderList',
  showFooter: true,//显示脚
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  scrollY:{ enabled: true },//开启虚拟滚动
  showOverflow:true,
  columnConfig: {
    resizable: true,
    useKey: true
  },
  filterConfig: {   //筛选配置项
    remote: true
  },
  customConfig: {
    storage: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'row',
    showStatus: true
  },
  data:  [
    {
      'id': '1',
      'long': '5',
      'wide': '1005',
      'thick': '183.6',
    }
  ]
})
</script>
<template>
  <div>
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">添加用户</el-button>
     <el-button type="primary" style="margin-top: 10px;margin-left: 10px;"  size="mini" id="searchButton" @click="add = true">{{ $t('productStock.addusers') }}</el-button>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;">
        <el-table height="240" ref="table" 
        @selection-change="handleSelectionChange"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="userName" align="center" label="用户名" min-width="180" />
          <el-table-column align="center" label="角色" min-width="80">
          <el-table-column prop="userName" align="center" :label="$t('productStock.username')" min-width="180" />
          <el-table-column align="center" :label="$t('productStock.role')" min-width="80">
            <template #default="scope">  
             <el-tag v-for="role in scope.row.roleList">  
            {{role.name}}  
           </el-tag>   
         </template> 
            </el-table-column>
          <el-table-column fixed="right" label="操作" align="center" width="200">
          <el-table-column fixed="right" :label="$t('productStock.operate')" align="center" width="270">
            <template #default="scope">
              <el-button size="mini" type="text" plain @click="open(scope.row)">重置密码</el-button>
              <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button>
              <el-button size="mini" type="text" plain @click="open(scope.row)">{{ $t('productStock.resetpassword') }}</el-button>
              <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">{{ $t('productStock.exit') }}</el-button>
              <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('productStock.delete') }}</el-button>
            </template>
        </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
  <el-dialog v-model="add" top="23vh" width="37%" title="添加用户" >
  <el-dialog v-model="add" top="23vh" width="37%" :title="$t('productStock.addusers')">
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form  size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
@@ -252,8 +228,8 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="用户名:" :required="true" style="width: 25vw">
                <el-input v-model="userName" autocomplete="off" />
          <el-form-item :label="$t('productStock.usernamea')" :required="true" style="width: 25vw">
                <el-input v-model="userName" autocomplete="off" :placeholder="$t('productStock.inusername')" />
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -261,19 +237,19 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="角色:" :required="true" style="width: 25vw;">
              <el-form-item :label="$t('productStock.rolea')" :required="true" style="width: 25vw;">
                <el-select
               v-model="selectedProjectNoa"
               filterable
               clearable
               placeholder="请选择角色"
               :placeholder="$t('productStock.inrole')"
               style="width: 330px"
             >
               <el-option
         v-for="item in titleSelectJsona['processTypea']"  
            :key="item.id"
            :label="item.name"
            :value="item.name"
            :value="item.id"
          />
        </el-select>
              </el-form-item></div></div>
@@ -283,9 +259,10 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="密码:" :required="true" style="width: 25vw;">
              <el-form-item :label="$t('productStock.password')" :required="true" style="width: 25vw;">
                <el-input style="width: 340px;"
                        v-model="password"
                        :placeholder="$t('productStock.inpassword')"
                        autocomplete="off"
                        :prefix-icon="Lock"
                        show-password/>
@@ -298,22 +275,22 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRow">
          确认
          {{ $t('productStock.sure') }}
        </el-button>
        <el-button @click="add = false">取消</el-button>
        <el-button @click="add = false">{{ $t('productStock.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
  <el-dialog v-model="adda" top="23vh" width="37%" title="修改用户" >
  <el-dialog v-model="adda" top="23vh" width="37%" :title="$t('productStock.reusername')" >
    <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;">
            <el-form :model="editingUser" ref="formRef" size="mini" label-width="150px">
            <el-form ref="formRef" size="mini" label-width="150px">
      <el-form label-width="100px" label-position="right">
        <el-row style="margin-top: -15px;margin-bottom: -2px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <el-form-item label="用户名:" :required="true" style="width: 25vw">
                <el-input v-model="editingUser.userName" autocomplete="off" />
          <el-form-item :label="$t('productStock.usernamea')" :required="true" style="width: 25vw">
                <el-input :placeholder="$t('productStock.inusername')" v-model="userName" autocomplete="off" />
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -321,41 +298,21 @@
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
          <!-- <el-table-column align="center" label="角色" min-width="80">
            <template #default="scope">
             <el-tag v-for="role in scope.row.roleList">
            {{role.name}}
           </el-tag>
         </template>
            </el-table-column> -->
              <el-form-item label="角色:" :required="true" style="width: 25vw;">
              <el-form-item :label="$t('productStock.rolea')" :required="true" style="width: 25vw;">
                <el-select
               v-model="selectedProjectNoa"
               filterable
               clearable
               placeholder="请选择角色"
               :placeholder="$t('productStock.inrole')"
               style="width: 330px"
             >
               <el-option
         v-for="item in titleSelectJsona['processTypea']"
         v-for="item in titleSelectJsona['processTypea']"
            :key="item.id"
            :label="item.name"
            :value="item.name"
            :value="item.id"
          />
        </el-select>
              </el-form-item></div></div>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px;">
          <el-col :span="6">
              <div id="dt" style="font-size: 15px;">
        <div>
              <el-form-item label="密码:" :required="true" style="width: 25vw;">
                <el-input style="width: 340px;"
                        v-model="editingUser.password"
                        autocomplete="off"
                        :prefix-icon="Lock"
                        show-password/>
              </el-form-item></div></div>
          </el-col>
        </el-row>
@@ -365,9 +322,9 @@
    <template #footer>
      <div id="dialog-footer">
        <el-button type="primary" @click="getTableRowa">
          确认
          {{ $t('productStock.sure') }}
        </el-button>
        <el-button @click="adda = false">取消</el-button>
        <el-button @click="adda = false">{{ $t('productStock.cancel') }}</el-button>
      </div>
    </template>
  </el-dialog> 
UI-Project/vite.config.js
@@ -1,17 +1,27 @@
import {fileURLToPath, URL} from 'node:url'
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import ReactivityTransform from '@vue-macros/reactivity-transform/vite'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    ReactivityTransform()
    ReactivityTransform(),
    AutoImport({
      imports: [
        'vue-i18n',
      ],
      dts: './auto-imports.d.ts',
      eslintrc: {
        enabled: false, // 配置更新时临时设为true,
      },
    }),
  ],
  resolve: {
    alias: {
      'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js',
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }, 
@@ -48,4 +58,4 @@
      })
    );
  },
});
});
hangzhoumesParent/JsonFile/PlcCacheVerticalGlass.json
@@ -1,57 +1,377 @@
{
  "plcAddressBegin":"DB.0",
  "plcAddressLenght":"72",
  "dataType":"word",
  "parameteInfor":[
    {
      "codeId": "D01Request",
      "addressIndex":"0",
      "addressLenght":"2",
      "ratio":"1",
      "unit":"m/min"
    },
    {
      "codeId": "D01ID1",
      "addressIndex":"2",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04Request",
      "addressIndex":"8",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04ID1",
      "addressIndex":"10",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D02Go",
      "addressIndex":"20",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D05Go",
      "addressIndex":"22",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ,
    {
      "codeId": "DeviceStatus",
      "addressIndex":"70",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ]
    "plcAddressBegin": "DB14.0",
    "plcAddressLenght": "938",
    "dataType": "word",
    "parameteInfor": [{
            "codeId": "D01ID",
            "addressIndex": "0",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D02ID",
            "addressIndex": "32",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID1",
            "addressIndex": "64",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID2",
            "addressIndex": "96",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID3",
            "addressIndex": "128",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID4",
            "addressIndex": "160",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID5",
            "addressIndex": "192",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID6",
            "addressIndex": "224",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ID",
            "addressIndex": "256",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID1",
            "addressIndex": "288",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID2",
            "addressIndex": "328",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID3",
            "addressIndex": "352",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID4",
            "addressIndex": "384",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID5",
            "addressIndex": "416",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID6",
            "addressIndex": "448",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID1",
            "addressIndex": "480",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID2",
            "addressIndex": "512",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID3",
            "addressIndex": "544",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID4",
            "addressIndex": "576",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID5",
            "addressIndex": "608",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID6",
            "addressIndex": "640",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID1",
            "addressIndex": "672",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID2",
            "addressIndex": "704",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID3",
            "addressIndex": "736",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID4",
            "addressIndex": "768",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID5",
            "addressIndex": "800",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID6",
            "addressIndex": "832",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ToMES",
            "addressIndex": "874",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ToMES",
            "addressIndex": "876",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D01ToMES",
            "addressIndex": "878",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ToMES",
            "addressIndex": "880",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD03",
            "addressIndex": "888",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD05",
            "addressIndex": "890",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToPLC",
            "addressIndex": "892",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport1",
            "addressIndex": "914",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport2",
            "addressIndex": "916",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport3",
            "addressIndex": "918",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport4",
            "addressIndex": "920",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport5",
            "addressIndex": "922",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport6",
            "addressIndex": "924",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport1",
            "addressIndex": "926",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport2",
            "addressIndex": "928",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport3",
            "addressIndex": "930",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport4",
            "addressIndex": "932",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport5",
            "addressIndex": "934",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport6",
            "addressIndex": "936",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "deviceState",
            "addressIndex": "864",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01State",
            "addressIndex": "866",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02State",
            "addressIndex": "868",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03State",
            "addressIndex": "870",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05State",
            "addressIndex": "872",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD01",
            "addressIndex": "894",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD04",
            "addressIndex": "896",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        }
    ]
}
hangzhoumesParent/JsonFile/PlcdownGlass.json
@@ -1,362 +1,144 @@
{
  "plcAddressBegin": "DB100.0",
  "plcAddressLenght": "142",
  "dataType": "word",
  "parameteInfor": [
    {
      "codeId": "RequestWord",
      "addressIndex": "0",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ID",
      "addressIndex": "2",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskRequestWord",
      "addressIndex": "4",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ID",
      "addressIndex": "6",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskRequestWord",
      "addressIndex": "8",
      "addressLenght": "2"
    },
    {
      "codeId": "G011ID",
      "addressIndex": "10",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "12",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "14",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "16",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "18",
      "addressLenght": "2"
    },
    {
      "codeId": "MESSendingWord",
      "addressIndex": "20",
      "addressLenght": "2"
    },
    {
      "codeId": "InputGrid",
      "addressIndex": "22",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputGrid",
      "addressIndex": "24",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputID",
      "addressIndex": "26",
      "addressLenght": "2"
    },
    {
      "codeId": "FrontOrRearLowerSlice",
      "addressIndex": "28",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "30",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskReply",
      "addressIndex": "32",
      "addressLenght": "2"
    },
    {
      "codeId": "G06Rack",
      "addressIndex": "34",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskReply",
      "addressIndex": "36",
      "addressLenght": "2"
    },
    {
      "codeId": "G11Rack",
      "addressIndex": "38",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "40",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "42",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "44",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "46",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "48",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "50",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "52",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "54",
      "addressLenght": "2"
    },
    {
      "codeId": "MESTaskState",
      "addressIndex": "56",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "58",
      "addressLenght": "2"
    },
    {
      "codeId": "AlarmState",
      "addressIndex": "60",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm1",
      "addressIndex": "62",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm2",
      "addressIndex": "64",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm3",
      "addressIndex": "66",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm4",
      "addressIndex": "68",
      "addressLenght": "2"
    },
    {
      "codeId": "neirong",
      "addressIndex": "70",
      "addressLenght": "2"
    },
    {
      "codeId": "device",
      "addressIndex": "72",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "74",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "76",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut1",
      "addressIndex": "78",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut2",
      "addressIndex": "80",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut3",
      "addressIndex": "82",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut4",
      "addressIndex": "84",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut5",
      "addressIndex": "86",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut6",
      "addressIndex": "88",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut7",
      "addressIndex": "90",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "92",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "94",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "96",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "98",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "100",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ActionState",
      "addressIndex": "102",
      "addressLenght": "2"
    },
    {
      "codeId": "G05ActionState",
      "addressIndex": "104",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ActionState",
      "addressIndex": "106",
      "addressLenght": "2"
    },
    {
      "codeId": "G07ActionState",
      "addressIndex": "108",
      "addressLenght": "2"
    },
    {
      "codeId": "G08ActionState",
      "addressIndex": "110",
      "addressLenght": "2"
    },
    {
      "codeId": "G09ActionState",
      "addressIndex": "112",
      "addressLenght": "2"
    },
    {
      "codeId": "G10ActionState",
      "addressIndex": "114",
      "addressLenght": "2"
    },
    {
      "codeId": "G11ActionState",
      "addressIndex": "116",
      "addressLenght": "2"
    },
    {
      "codeId": "G12ActionState",
      "addressIndex": "118",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ActionState",
      "addressIndex": "120",
      "addressLenght": "2"
    },
    {
      "codeId": "G04IDS",
      "addressIndex": "122",
      "addressLenght": "2"
    },
    {
      "codeId": "G05IDS",
      "addressIndex": "124",
      "addressLenght": "2"
    },
    {
      "codeId": "G06IDS",
      "addressIndex": "126",
      "addressLenght": "2"
    },
    {
      "codeId": "G07IDS",
      "addressIndex": "128",
      "addressLenght": "2"
    },
    {
      "codeId": "G08IDS",
      "addressIndex": "130",
      "addressLenght": "2"
    },
    {
      "codeId": "G09IDS",
      "addressIndex": "132",
      "addressLenght": "2"
    },
    {
      "codeId": "G10IDS",
      "addressIndex": "134",
      "addressLenght": "2"
    },
    {
      "codeId": "G11IDS",
      "addressIndex": "136",
      "addressLenght": "2"
    },
    {
      "codeId": "G12IDS",
      "addressIndex": "138",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ID",
      "addressIndex": "140",
      "addressLenght": "2"
    }
  ]
    "plcAddressBegin": "DB11.0",
    "plcAddressLenght": "100",
    "dataType": "word",
    "parameteInfor": [
        {
            "codeId": "requestWord",
            "addressIndex": "0",
            "addressLenght": "2"
        },
        {
            "codeId": "requestID",
            "addressIndex": "2",
            "addressLenght": "30"
        },
        {
            "codeId": "currentCell",
            "addressIndex": "32",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus08",
            "addressIndex": "36",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_glass_status",
            "addressIndex": "40",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_glass_status",
            "addressIndex": "42",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_glass_status",
            "addressIndex": "44",
            "addressLenght": "2"
        },
        {
            "codeId": "G04_error_status",
            "addressIndex": "48",
            "addressLenght": "2"
        },
        {
            "codeId": "G05_error_status",
            "addressIndex": "50",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_error_status",
            "addressIndex": "52",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "54",
            "addressLenght": "2"
        },
        {
            "codeId": "G08_error_status",
            "addressIndex": "56",
            "addressLenght": "2"
        },
        {
            "codeId": "G09_error_status",
            "addressIndex": "58",
            "addressLenght": "2"
        },
        {
            "codeId": "G10_error_status",
            "addressIndex": "60",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_error_status",
            "addressIndex": "62",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "64",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_error_status",
            "addressIndex": "66",
            "addressLenght": "2"
        },
        {
            "codeId": "confirmationWord",
            "addressIndex": "72",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_prohibit_film_production",
            "addressIndex": "74",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_prohibit_film_production",
            "addressIndex": "76",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_prohibit_film_production",
            "addressIndex": "78",
            "addressLenght": "2"
        },
        {
            "codeId": "Glass_width",
            "addressIndex": "82",
            "addressLenght": "4"
        },
        {
            "codeId": "Glass_height",
            "addressIndex": "86",
            "addressLenght": "4"
        },
        {
            "codeId": "Glass_thickness",
            "addressIndex": "90",
            "addressLenght": "4"
        },
        {
            "codeId": "Start_cell",
            "addressIndex": "94",
            "addressLenght": "2"
        },
        {
            "codeId": "End_cell",
            "addressIndex": "96",
            "addressLenght": "2"
        },
        {
            "codeId": "task_type",
            "addressIndex": "98",
            "addressLenght": "2"
        }
    ]
}
hangzhoumesParent/common/servicebase/pom.xml
@@ -19,8 +19,8 @@
    <dependencies>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
            <artifactId>mssql-jdbc</artifactId>
            <version>6.4.0.jre8</version>
        </dependency>
    </dependencies>
hangzhoumesParent/common/servicebase/src/main/java/com/mes/base/entity/BigStorageCageBaseInfo.java
New file
@@ -0,0 +1,32 @@
package com.mes.base.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @Author : zhoush
 * @Date: 2024/6/21 9:40
 * @Description:
 */
@Data
public class BigStorageCageBaseInfo {
    /**
     * 玻璃id
     */
    @ApiModelProperty(value = "玻璃id")
    private String glassId;
    /**
     * 宽
     */
    @ApiModelProperty(value = "宽")
    private double width;
    /**
     * 格子号
     */
    @ApiModelProperty(value = "玻璃id")
    private Integer slot;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/common/config/Const.java
@@ -18,28 +18,38 @@
     * 磨边清洗前
     */
    /**
     * A09出片目标位置2001
     * A10出片目标位置2002
     * A09出片目标位置  d02卧转立    2001
     * A10出片目标位置  d05卧转立    2002
     */
    public static final Integer A09_OUT_TARGET_POSITION = 2001;
    public static final Integer A10_OUT_TARGET_POSITION = 2002;
    /**
     * A09出片目标位置  d02卧转立 钢化出片    3001
     * A10出片目标位置  d05卧转立 人工出片    3002
     */
    //todo:临时将钢化出片线路改为人工出片
    public static final Integer TEMPERING_OUT_TARGET_POSITION = 3002;
    public static final Integer ARTIFICIAL_OUT_TARGET_POSITION = 3002;
    /**
     * 卧式理片笼详情表玻璃状态
     * 识别后成功状态100
     * 出片任务101
     * 人工下片102
     * 拿走200
     * 破损201
     */
    public static final Integer GLASS_STATE_IN = 100;
    public static final Integer GLASS_STATE_OUT = 101;
    public static final Integer GLASS_STATE_ARTIFICIAL = 102;
    public static final Integer GLASS_STATE_TAKE = 200;
    public static final Integer GLASS_STATE_DAMAGE = 201;
    /**
     * 卧式理片笼详情表玻璃状态
     * 进片任务1
     * 出片任务2
     * 出片任务2
     */
    public static final Integer GLASS_CACHE_TYPE_IN = 1;
@@ -71,8 +81,8 @@
     * 0 大理片笼无请求
     * 1 大理片笼进片请求
     */
    public static final Integer BIG_STORAGE_REQUEST = 0;
    public static final Integer BIG_STORAGE_REQUEST_IN = 1;
    public static final String BIG_STORAGE_REQUEST = "0";
    public static final String BIG_STORAGE_REQUEST_IN = "1";
    /**
     * 卧转立进片请求
@@ -85,6 +95,7 @@
    public static final Integer BIG_STORAGE_IN_UP = 2;
    public static final Integer BIG_STORAGE_IN_CAR = 3;
    public static final Integer BIG_STORAGE_IN_SLOT = 4;
    public static final List<Integer> BIG_STORAGE_IN_UP_ALL = Arrays.asList(1, 2);
    /**
     * 卧转立出片请求
     * 1 任务生成
@@ -104,12 +115,6 @@
    public static final Integer BIG_STORAGE_IN_RUN = 2;
    /**
     * 大理片笼宽度 及 玻璃间距
     */
    public static final Integer BIG_STORAGE_WIDTH = 5000;
    public static final Integer BIG_STORAGE_GAP = 20;
    /**
     * 钢化小片表
     * -1 生成任务
     * 0  出片完成
@@ -121,13 +126,30 @@
     * 6  拿走
     */
    public static final Integer TEMPERING_NEW =-1;
    public static final Integer TEMPERING_OUT =0;
    public static final Integer TEMPERING_DROP =1;
    public static final Integer TEMPERING_START =2;
    public static final Integer TEMPERING_SUCCESS =3;
    public static final Integer TEMPERING_END =4;
    public static final Integer TEMPERING_DAMAGE =5;
    public static final Integer TEMPERING_TAKE =6;
    public static final Integer TEMPERING_NEW = -1;
    public static final Integer TEMPERING_OUT = 0;
    public static final Integer TEMPERING_DROP = 1;
    public static final Integer TEMPERING_START = 2;
    public static final Integer TEMPERING_SUCCESS = 3;
    public static final Integer TEMPERING_END = 4;
    public static final Integer TEMPERING_DAMAGE = 5;
    public static final Integer TEMPERING_TAKE = 6;
    /**
     * 下片
     */
    /**
     * 执行线路格子信息
     */
    public static final List<Integer> G06_WORK_STATION = Arrays.asList(1, 2, 3);
    public static final List<Integer> G11_WORK_STATION = Arrays.asList(4, 5, 6);
    public static final List<Integer> G13_WORK_STATION = Arrays.asList(7);
    /**
     * 启用 1
     * 禁用 0
     */
    public static final Integer SLOT_ON = 1;
    public static final Integer SLOT_OFF = 0;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/controller/DamageController.java
New file
@@ -0,0 +1,51 @@
package com.mes.damage.controller;
import cn.hutool.core.date.DateTime;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.utils.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wu
 * @since 2024-06-25
 */
@RestController
@RequestMapping("/damage")
public class DamageController {
    @Autowired
    private DamageService damageService;
    @ApiOperation("报工数据查询")
    @GetMapping("/selectDamage")
    public Result selectDamage(DateTime startTime , DateTime endTime,int type,int status,int workingProcedureId) {
        return Result.build(200,"查询成功",damageService.selectDamage(startTime,endTime,type,status,workingProcedureId));
    }
    @ApiOperation("报工")
    @GetMapping("/submitDamage")
    public Result submitDamage(DateTime startTime , DateTime endTime,int type,int status,int workingProcedureId) {
        damageService.submitDamage(startTime,endTime,type,status,workingProcedureId);
        return Result.build(200,"报工成功",1);
    }
    @ApiOperation("报工数据修改")
    @GetMapping("/updateDamage")
    public Result updateDamage(List<Damage> damageList) {
        damageService.updateBatchById(damageList);
        return Result.build(200,"修改成功",1);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/entity/Damage.java
New file
@@ -0,0 +1,128 @@
package com.mes.damage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-25
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Damage implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 线路
     */
    private Integer line;
    /**
     * 工序
     */
    private Integer workingProcedure;
    /**
     * 玻璃id
     */
    private String glassId;
    /**
     * 工程号
     */
    private String engineerId;
    /**
     * 钢化版图id
     */
    private Integer temperingLayoutId;
    /**
     * 生产时间
     */
    private LocalDateTime damageTime;
    /**
     * 备注
     */
    private String remark;
    /**
     * 类型:0:报工 1:破损 2:拿走
     */
    private Integer type;
    /**
     * 状态:0:未报工 1:已报工
     */
    private Integer status;
    /**
     * 流程卡
     */
    private String processId;
    /**
     * 序号
     */
    private Integer orderNumber;
    /**
     * 工艺确认序号
     */
    private Integer technologyNumber;
    /**
     * 破损类型
     */
    private String breakageType;
    /**
     * 破损原因
     */
    private String breakageReason;
    /**
     * 责任工序
     */
    private String responsibleProcess;
    /**
     * 责任人员
     */
    private String responsiblePersonnel;
    /**
     * 责任班组
     */
    private String responsibleTeam;
    /**
     * 责任设备
     */
    private String responsibleEquipment;
    /**
     * 报工班组名称
     */
    private String teamsGroupsName;
    /**
     * 报工设备名称
     */
    private String deviceName;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/mapper/DamageMapper.java
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/service/DamageService.java
New file
@@ -0,0 +1,24 @@
package com.mes.damage.service;
import cn.hutool.core.date.DateTime;
import com.mes.damage.entity.Damage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 *  服务类
 * </p>
 *
 * @author wu
 * @since 2024-06-13
 */
public interface DamageService extends IService<Damage> {
    List<Damage> selectDamage(DateTime startTime, DateTime endTime, int type, int status, int workingProcedureId);
    void submitDamage(DateTime startTime, DateTime endTime, int type, int status, int workingProcedureId);
    void insertDamage(Damage damage);
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/damage/service/impl/DamageServiceImpl.java
New file
@@ -0,0 +1,102 @@
package com.mes.damage.service.impl;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mes.damage.entity.Damage;
import com.mes.damage.mapper.DamageMapper;
import com.mes.damage.service.DamageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.mapper.GlassInfoMapper;
import com.mes.work_assignment.entity.WorkAssignment;
import com.mes.work_assignment.mapper.WorkAssignmentMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wu
 * @since 2024-06-13
 */
@Service
public class DamageServiceImpl extends ServiceImpl<DamageMapper, Damage> implements DamageService {
    @Resource
    GlassInfoMapper glassInfoMapper;
    @Resource
    WorkAssignmentMapper workAssignmentMapper;
    /**
     * 查询报工信息
     */
    @Override
    public List<Damage> selectDamage(DateTime startTime, DateTime endTime, int type, int status, int workingProcedureId){
        LambdaQueryWrapper<Damage> damageSelectWrapper =new LambdaQueryWrapper<>();
        damageSelectWrapper.between(Damage::getDamageTime,startTime,endTime);
        if (type!=0){
            damageSelectWrapper.eq(Damage::getType,type);
        }
        if (status!=0){
            damageSelectWrapper.eq(Damage::getStatus,status);
        }
        if(workingProcedureId!=0){
            damageSelectWrapper.eq(Damage::getWorkingProcedure,workingProcedureId);
        }
        return baseMapper.selectList(damageSelectWrapper);
    }
    /**
     * 提交报工
     */
    @Override
    public void submitDamage(DateTime startTime, DateTime endTime, int type, int status, int workingProcedureId){
        LambdaUpdateWrapper<Damage> damageUpdateWrapper=new LambdaUpdateWrapper<>();
        damageUpdateWrapper.between(Damage::getDamageTime,startTime,endTime);
        if (type!=0){
            damageUpdateWrapper.eq(Damage::getType,type);
        }
        if (status!=0){
            damageUpdateWrapper.eq(Damage::getStatus,status);
        }
        if(workingProcedureId!=0){
            damageUpdateWrapper.eq(Damage::getWorkingProcedure,workingProcedureId);
        }
        Damage damage=new Damage();
        damage.setStatus(2);
        baseMapper.update(damage,damageUpdateWrapper);
    }
    /**
     * 添加报工信息
     */
    @Override
    public void insertDamage(Damage damage){
        LambdaQueryWrapper<GlassInfo> glassInfoSelectWrapper=new LambdaQueryWrapper<>();
        glassInfoSelectWrapper.eq(GlassInfo::getGlassId,damage.getGlassId());
        GlassInfo glassInfo=glassInfoMapper.selectOne(glassInfoSelectWrapper);
        LambdaQueryWrapper<WorkAssignment> workAssignmentSelectWrapper=new LambdaQueryWrapper<>();
        workAssignmentSelectWrapper
                .eq(WorkAssignment::getLine,damage.getLine())
                .eq(WorkAssignment::getWorkProcesses,damage.getWorkingProcedure());
        WorkAssignment workAssignment=workAssignmentMapper.selectOne(workAssignmentSelectWrapper);
        damage.setTeamsGroupsName(workAssignment.getTeamsGroupsName());
        damage.setDeviceName(workAssignment.getDeviceName());
        damage.setEngineerId(glassInfo.getEngineerId());
        damage.setTemperingLayoutId(glassInfo.getTemperingLayoutId());
        damage.setProcessId(glassInfo.getFlowCardId());
        damage.setOrderNumber(glassInfo.getGlassType());
        damage.setTechnologyNumber(glassInfo.getLayer());
        damage.setDamageTime(LocalDateTime.now());
        baseMapper.insert(damage);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/entity/GlassInfo.java
@@ -35,22 +35,22 @@
    /**
     * 流程卡玻璃类型
     */
    private String glassType;
    private Integer glassType;
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 膜系
@@ -70,12 +70,12 @@
    /**
     * 磨前宽
     */
    private Double edgWidth;
    private double edgWidth;
    /**
     * 磨前高
     */
    private Double edgHeight;
    private double edgHeight;
    /**
     * 是否配片
@@ -85,12 +85,12 @@
    /**
     * 配片最大宽
     */
    private Double maxWidth;
    private double maxWidth;
    /**
     * 配片最大高
     */
    private Double maxHeight;
    private double maxHeight;
    /**
     * 钢化是否接受横放
@@ -125,7 +125,7 @@
    /**
     * 旋转角度(逆时针)
     */
    private Integer angle;
    private double angle;
    /**
     * 工程号
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/entity/OptimizeGlassinfo.java
@@ -25,17 +25,28 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 宽
     */
    private double oHeight;
    /**
     * 高
     */
    private double oWidth;
    /**
     * 厚度
     */
    private Double glassThickness;
    private double glassThickness;
    /**
     * 玻璃膜系
@@ -55,11 +66,11 @@
    /**
     * 小片宽(加磨量)
     */
    private Double pWidth;
    private double pWidth;
    /**
     * 小片高(加磨量)
     */
    private Double pHeight;
    private double pHeight;
    /**
     * 版图id
     */
@@ -88,5 +99,13 @@
     * 小片编号
     */
    private  String glassId;
    /**
     * 订单序号
     */
    private Integer orderSort;
    /**
     * 旋转角度
     */
    private double rotateAngle;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/mapper/GlassInfoMapper.java
@@ -2,16 +2,15 @@
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.glassinfo.entity.GlassInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 *  Mapper 接口
 * Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-04-29
 */
public interface GlassInfoMapper extends BaseMapper<GlassInfo>, MPJBaseMapper<GlassInfo> {
public interface GlassInfoMapper extends MPJBaseMapper<GlassInfo> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/glassinfo/service/impl/GlassInfoServiceImpl.java
@@ -1,6 +1,7 @@
package com.mes.glassinfo.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJQueryWrapper;
import com.mes.glassinfo.entity.GlassInfo;
@@ -14,11 +15,14 @@
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
 *  服务实现类
 * 服务实现类
 * </p>
 *
 * @author wu
@@ -29,22 +33,24 @@
public class GlassInfoServiceImpl extends MPJBaseServiceImpl<GlassInfoMapper, GlassInfo> implements GlassInfoService {
    @Autowired
    OptimizeProjectMapper optimizeProjectMapper;
    @Override
    @DS("pp")
    public List<GlassInfo> selectGlassInfo(String engineeringId) {
        List<OptimizeGlassinfo> optimizeGlassinfos=null;
        List<OptimizeGlassinfo> optimizeGlassinfos = null;
        if (engineeringId != null) {
            optimizeGlassinfos = optimizeProjectMapper.selectJoinList(OptimizeGlassinfo.class, new MPJQueryWrapper<OptimizeProject>()
                    .select("b.process_id,t.type,b.width,b.height,t.glass_thickness,t.glass_type,b.p_width,b.p_height,b.layer, b.total_layer, b.stock_id,b.heat_layout_id,b.heat_layout_sort,b.x_axis,b.y_axis,b.project_no,b.glass_id")
                    .select("b.process_id,t.glass_type,b.o_width,b.o_height,t.glass_thickness,b.order_sort,b.p_width,b.p_height,b.layer, b.total_layer, b.stock_id,b.heat_layout_id,b.heat_layout_sort,c.x_axis,c.y_axis,b.project_no,b.glass_id,c.rotate_angle")
                    .leftJoin("optimize_detail b on t.project_no=b.project_no")
                                    .leftJoin("optimize_heat_detail c on c.project_no=t.project_no and b.heat_layout_id=c.layout_id and b.heat_layout_sort=c.sort")
                    //.eq("t.state",100)
                    .eq("t.project_no", engineeringId));
        }
        //order_sort,o_width,o_height
        // 创建一个 List 用于保存映射后的实体对象
        List<GlassInfo> resultList = new ArrayList<>();
        if(optimizeGlassinfos!=null){
        if (optimizeGlassinfos != null) {
            for (OptimizeGlassinfo map : optimizeGlassinfos) {
                // 创建一个新的 OptimizeGlassinfo 对象
                GlassInfo glassInfo = new GlassInfo();
@@ -52,9 +58,9 @@
                glassInfo.setEngineerId(map.getProjectNo());
                glassInfo.setFlowCardId(map.getProcessId());
                glassInfo.setFilmsid(map.getGlassType());
                glassInfo.setGlassType(map.getType());
                glassInfo.setWidth(map.getWidth());
                glassInfo.setHeight(map.getHeight());
                glassInfo.setGlassType(map.getOrderSort());//订单序号
                glassInfo.setWidth(map.getOWidth());//订单宽
                glassInfo.setHeight(map.getOHeight());//订单高
                glassInfo.setEdgWidth(map.getPWidth());
                glassInfo.setLayer(map.getLayer());
                glassInfo.setTotalLayer(map.getTotalLayer());
@@ -65,14 +71,14 @@
                glassInfo.setTemperingFeedSequence(map.getHeatLayoutSort());//钢化版图顺序
                glassInfo.setXCoordinate(map.getXAxis());
                glassInfo.setYCoordinate(map.getYAxis());
                glassInfo.setAngle(map.getRotateAngle());
                glassInfo.setGlassId(map.getGlassId());
                // 将映射后的对象添加到结果列表中
                resultList.add(glassInfo);
            }
        }
        log.info("查询出glassinfo的数据{}:",resultList);
        log.info("查询出glassinfopro的数据{}:",optimizeGlassinfos);
        log.info("查询出glassinfo的数据{}:", resultList);
        log.info("查询出glassinfopro的数据{}:", optimizeGlassinfos);
        return resultList;
    }
@@ -80,4 +86,46 @@
    public void saveGlassInfo(List<GlassInfo> glassinfo) {
        this.saveBatch(glassinfo);
    }
    @Override
    public int getGlassInfoCountByFlowCardId(String flowCardId) {
        return baseMapper.selectCount(new QueryWrapper<GlassInfo>().lambda()
                .eq(GlassInfo::getFlowCardId, flowCardId));
    }
    @Override
    public List<Map<String, Object>> getFlowCardId() {
        // 第二个查询:查询 OptimizeProject 表,根据 GlassInfo 的 engineerId 和 state 进行筛选
        List<OptimizeProject> optimizeProjects = optimizeProjectMapper.selectList(
                new QueryWrapper<OptimizeProject>()
                        .ne("state", 300)
        );
        // 提取 engineerId 列表
        List<String> engineerIds = optimizeProjects.stream()
                .map(OptimizeProject::getProjectNo)
                .collect(Collectors.toList());
        // 第一个查询:查询 GlassInfo 表并按 flow_card_id 分组,同时筛选出在 engineerIds 列表中的记录
        List<GlassInfo> glassInfos = baseMapper.selectList(
                new QueryWrapper<GlassInfo>()
                        .in("engineer_id", engineerIds)
                        .groupBy("flow_card_id")
        );
        // 转换为 List<Map<String, Object>>
        List<Map<String, Object>> result = glassInfos.stream()
                .map(glassInfo -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("flow_card_id", glassInfo.getFlowCardId());
                    // 如果还有其他字段需要添加到 map 中,在这里继续添加
                    return map;
                })
                .collect(Collectors.toList());
        log.info("result: {}", result);
        return result;
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/controller/OrderController.java
New file
@@ -0,0 +1,39 @@
package com.mes.order.controller;
import com.mes.order.entity.Orderdetail;
import com.mes.order.entity.Orders;
import com.mes.order.service.OrdersService;
import com.mes.utils.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
@RestController
@RequestMapping("/order/order")
@Slf4j
public class OrderController {
    @Autowired
    //获取待选择的工程号
    private OrdersService ordersService;
    @ApiOperation("显示订单详细")
    @PostMapping("/selectOrderdetail") //显示工程选择信息
    @ResponseBody
    public Result<List<Orderdetail>> listByState(@RequestBody Orders orders) {
        log.info("将请求参数封装在请求类里面");
        List<Orderdetail> glass = ordersService.selectOrderdetail(orders);
        log.info("显示订单详情信息:{}", glass);
        return Result.build(200, "", glass);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Order.java
New file
@@ -0,0 +1,232 @@
package com.mes.order.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Order implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * <订单表>
     */
      @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 订单Id
     */
    private String orderId;
    /**
     * 项目名称
     */
    private String project;
    /**
     * 客户Id
     */
    private Long customerId;
    /**
     * 客户名称
     */
    private String customerName;
    /**
     * 订单类型
     */
    private String orderType;
    /**
     * 订单分类
     */
    private String orderClassify;
    /**
     * 商标选项
     */
    private String icon;
    /**
     * 包装方式
     */
    private String packType;
    /**
     * 送货时间
     */
    private LocalDateTime deliveryDate;
    /**
     * 批次
     */
    private String batch;
    /**
     * 计算方式
     */
    private Integer calculateType;
    /**
     * 销售人员Id
     */
    private String salesmanId;
    /**
     * 销售人
     */
    private String salesman;
    /**
     * 铝条方式
     */
    private String alType;
    /**
     * 金额
     */
    private BigDecimal money;
    /**
     * 合同编号
     */
    private String contractId;
    /**
     * 客户批次
     */
    private String customerBatch;
    /**
     * 联系人
     */
    private String contacts;
    /**
     * 联系电话
     */
    private String contactNumber;
    /**
     * 送货地址
     */
    private String deliveryAddress;
    /**
     * 其他金额
     */
    private BigDecimal otherMoney;
    /**
     * 其他金额备注
     */
    private String otherMoneyRemarks;
    /**
     * 订单加工备注
     */
    private String processingNote;
    /**
     * 其他备注
     */
    private String otherRemarks;
    /**
     * 面积
     */
    private BigDecimal area;
    /**
     * 数量
     */
    private Long quantity;
    /**
     * 周长
     */
    private String perimeter;
    /**
     * 审核人id
     */
    private String verifierId;
    /**
     * 审核人
     */
    private String verifier;
    /**
     * 创建人id
     */
    private String creatorId;
    /**
     * 创建人
     */
    private String creator;
    /**
     * 下单
     */
    private Integer createOrder;
    /**
     * 工艺审核
     */
    private Integer processReview;
    /**
     * 订单审核
     */
    private Integer orderReview;
    /**
     * 生产订单
     */
    private Integer productionOrder;
    /**
     * 流程卡
     */
    private Integer processingCard;
    /**
     * 入库    未入库状态0,未完全入库状态1,完全入库状态2
     */
    private Integer warehousing;
    /**
     * 发货
     */
    private Integer delivery;
    /**
     * 创建日期
     */
    private LocalDateTime createTime;
    /**
     * 修改时间
     */
    private LocalDateTime updateTime;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Orderdetail.java
New file
@@ -0,0 +1,65 @@
package com.mes.order.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Orderdetail implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 订单Id
     */
    private String orderId;
    /**
     * 项目名称
     */
    private String project;
    /**
     * 产品名称
     */
    private String productName;
    /**
     * 宽
     */
    private String width;
    /**
     * 高
     */
    private String height;
    /**
     * 面积
     */
    private double area;
    /**
     * 包装方式
     */
    private Integer quantity;
    /**
     * 状态
     */
    private String processingNote;
    /**
     * 送货时间
     */
    private String deliveryDate;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/entity/Orders.java
New file
@@ -0,0 +1,63 @@
package com.mes.order.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Orders implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * <订单表>
     */
    /**
     * 订单Id
     */
    private String orderId;
    /**
     * 客户名称
     */
    private String customerName;
    /**
     * 项目名称
     */
    private String project;
    /**
     * 面积
     */
    private double area;
    /**
     * 包装方式
     */
    private Integer quantity;
    /**
     * 状态
     */
    private Integer warehousing;
    /**
     * 送货时间
     */
    private String deliveryDate;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrderMapper.java
New file
@@ -0,0 +1,16 @@
package com.mes.order.mapper;
import com.mes.order.entity.Order;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
public interface OrderMapper extends BaseMapper<Order> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrderdetailMapper.java
New file
@@ -0,0 +1,15 @@
package com.mes.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.order.entity.Orderdetail;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
public interface OrderdetailMapper extends BaseMapper<Orderdetail> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/OrdersMapper.java
New file
@@ -0,0 +1,15 @@
package com.mes.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.order.entity.Orders;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
public interface OrdersMapper extends BaseMapper<Orders> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/mapper/xml/OrderMapper.xml
New file
@@ -0,0 +1,5 @@
<?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 namespace="com.mes.order.mapper.OrderMapper">
</mapper>
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/service/OrdersService.java
New file
@@ -0,0 +1,23 @@
package com.mes.order.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.order.entity.Order;
import com.mes.order.entity.Orderdetail;
import com.mes.order.entity.Orders;
import java.util.List;
/**
 * <p>
 *  服务类
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
public interface OrdersService extends IService<Orders> {
    List<Orders> selectOrders();
    List<Orderdetail> selectOrderdetail(Orders orders);
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/order/service/impl/OrdersServiceImpl.java
New file
@@ -0,0 +1,44 @@
package com.mes.order.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.order.entity.Orderdetail;
import com.mes.order.entity.Orders;
import com.mes.order.mapper.OrderdetailMapper;
import com.mes.order.mapper.OrdersMapper;
import com.mes.order.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wu
 * @since 2024-06-17
 */
@Service
@DS("sd")
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
@Autowired
private OrderdetailMapper orderdetailMapper;
    @Override
    public List<Orders> selectOrders() {
        //获取所有未完成的订单
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("warehousing", "2");
        return baseMapper.selectList(queryWrapper);
    }
    @Override
    public List<Orderdetail> selectOrderdetail(Orders orders) {
        QueryWrapper<Orderdetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orders.getOrderId());
        return orderdetailMapper.selectList(queryWrapper);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/controller/ReportingWorkController.java
New file
@@ -0,0 +1,40 @@
package com.mes.pp.controller;
import com.mes.pp.entity.request.OptimizeRequest;
import com.mes.pp.entity.request.Reportingdamage;
import com.mes.pp.service.ReportingWorkService;
import com.mes.utils.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
@RestController
@RequestMapping("/reporting_work/reporting-work")
@Slf4j
public class ReportingWorkController {
    @Autowired
    private ReportingWorkService reportingWorkService;
    @ApiOperation("显示工程选择信息")
    @PostMapping("/selectDamage") //显示工程选择信息
    @ResponseBody
    public Result<List<Reportingdamage>> selectDamage(@RequestBody Reportingdamage reportingdamage) {
        log.info("将请求参数封装在请求类里面");
        List<Reportingdamage> glass = reportingWorkService.selectDamage(reportingdamage);
        log.info("显示工程选择信息:{}", glass);
        return Result.build(200, "", glass);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeDetail.java
@@ -73,32 +73,32 @@
    /**
     * 小片宽(加磨量)
     */
    private Double pWidth;
    private double pWidth;
    /**
     * 小片高(加磨量)
     */
    private Double pHeight;
    private double pHeight;
    /**
     * 小片宽
     */
    private Double width;
    private double width;
    /**
     * 小片高
     */
    private Double height;
    private double height;
    /**
     * x坐标
     */
    private Double xAxis;
    private double xAxis;
    /**
     * y坐标
     */
    private Double yAxis;
    private double yAxis;
    /**
     * 钢化版图编号(架号)
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeLayout.java
@@ -36,13 +36,13 @@
     */
    private Integer stockId;
    private Double width;
    private double width;
    private Double height;
    private double height;
    private Double realwidth;
    private double realwidth;
    private Double realheight;
    private double realheight;
    /**
     * 切裁率
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/OptimizeProject.java
@@ -67,7 +67,7 @@
    /**
     * 总面积
     */
    private Double glassTotalArea;
    private double glassTotalArea;
    /**
     * 流程卡数量
@@ -87,7 +87,7 @@
    /**
     * 第一次平均切裁率
     */
    private Double fristCutPct;
    private double fristCutPct;
    /**
     * 使用的原料数
@@ -97,22 +97,22 @@
    /**
     * 使用的原料面积
     */
    private Double rawStockArea;
    private double rawStockArea;
    /**
     * 平均切裁率
     */
    private Double avgCutPct;
    private double avgCutPct;
    /**
     * 有效切裁率
     */
    private Double validCutPct;
    private double validCutPct;
    /**
     * 尾片切裁率
     */
    private Double lastCutPct;
    private double lastCutPct;
    /**
     * g混排程度
@@ -137,27 +137,27 @@
    /**
     * g上片宽
     */
    private Double loadWidth;
    private double loadWidth;
    /**
     * g上片长
     */
    private Double loadLength;
    private double loadLength;
    /**
     * x间隔
     */
    private Double xSpace;
    private double xSpace;
    /**
     * y间隔
     */
    private Double ySpace;
    private double ySpace;
    /**
     * g平均装载率
     */
    private Double loadRate;
    private double loadRate;
    /**
     * 流程卡集合
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/ReportingWork.java
New file
@@ -0,0 +1,176 @@
package com.mes.pp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ReportingWork implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * <报工主表>
     */
      @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 报工编号
     */
    private String reportingWorkId;
    /**
     * 销售单号
     */
    private String orderId;
    /**
     * 生产订单号
     */
    private String productionId;
    /**
     * 流程卡号
     */
    private String processId;
    /**
     * 本工序
     */
    private String thisProcess;
    /**
     * 设备编号
     */
    private byte[] deviceId;
    /**
     * 设备名称
     */
    private String deviceName;
    /**
     * 上工序
     */
    private String previousProcess;
    /**
     * 上工序数量
     */
    private Integer previousProcessQuantity;
    /**
     * 本工序数量
     */
    private Integer thisProcessQuantity;
    /**
     * 本工序完工数
     */
    private Integer thisCompletedQuantity;
    /**
     * 本工序次破数
     */
    private Integer thisWornQuantity;
    /**
     * 下工序
     */
    private String nextProcess;
    /**
     * 班次
     */
    private String classes;
    /**
     * 班组编号
     */
    private String teamsGroupsId;
    /**
     * 班组名称
     */
    private String teamsGroupsName;
    /**
     * 报工状态
     */
    private Integer reportingWorkState;
    /**
     * 审核人
     */
    private String reviewed;
    /**
     * 审核状态(默认0,审核通过1,不通过2,小于0删除)
     */
    private Integer reviewedState;
    /**
     * 备注
     */
    private String notes;
    /**
     * 质检员
     */
    private String qualityInspector;
    /**
     * 包装方式
     */
    private String packagingMethod;
    /**
     * 报工时间
     */
    private LocalDateTime reportingWorkTime;
    /**
     * 审核时间
     */
    private LocalDateTime examineTime;
    /**
     * 质检时间
     */
    private LocalDateTime qualityInsTime;
    /**
     * 创建者id
     */
    private String creatorId;
    /**
     * 创建者
     */
    private String creator;
    /**
     * 建立时间
     */
    private LocalDateTime createTime;
    /**
     * 修改时间
     */
    private LocalDateTime updateTime;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/request/AwaitingRepair.java
New file
@@ -0,0 +1,161 @@
package com.mes.pp.entity.request;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class AwaitingRepair implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 次破时间
     */
    private String reportingWorkTime;
    /**
     * 订单号
     */
    private String orderId;
    /**
     * 报工编号
     */
    private String reportingWorkId;
    /**
     * 生产订单号
     */
    private String productionId;
    /**
     * 流程卡号
     */
    private String processId;
    /**
     * 项目名称
     */
    private String project;
    /**
     * 批次
     */
    private String batch;
    /**
     * 明细id
     */
    private String reviewer;
    /**
     * 楼号
     */
    private String buildingNumber;
    /**
     * 订单序号
     */
    private Integer orderSort;
    /**
     * 产品名称
     */
    private String productName;
    /**
     * 工艺确认序号
     */
    private Integer technologyNumber;
    /**
     * 片标记(位置)
     */
    private String glassAddress;
    /**
     * 补片数量
     */
    private Integer patchNum;
    /**
     * 宽
     */
    private double width;
    /**
     * 高
     */
    private double height;
    /**
     * 形状
     */
    private String shape;
    /**
     * 责任工序
     */
    private String responsibleProcess;
    /**
     * 本工序
     */
    private String patchProcesses;
    /**
     * 次破未补数量
     */
    private Integer breakageQuantity;
    /**
     * 退回工序
     */
    private String returnProcesses;
    /**
     * 次破原因
     */
    private String patchReason;
    /**
     * 次破类型
     */
    private String patchType;
    /**
     * 责任人员
     */
    private String responsiblePersonnel;
    /**
     * 责任设备
     */
    private String responsibleEquipment;
    /**
     * 责任班组
     */
    private String responsibleTeam;
    /**
     * 次破面积
     */
    private double patchArea;
    /**
     * 质检员
     */
    private String qualityInspector;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/entity/request/Reportingdamage.java
New file
@@ -0,0 +1,38 @@
package com.mes.pp.entity.request;
import cn.hutool.core.date.DateTime;
import lombok.Data;
import java.time.LocalDate;
/**
 * @author wu
 */
@Data
public class Reportingdamage {
    /**
     * 工序
     */
    private String thisProcess;
    /**
     * 设备
     */
    private String deviceName;
    /**
     * 加工数量
     */
    private Integer completedQuantity;
    /**
     * 次破数量
     */
    private Integer breakageQuantity;
    /**
     * 次破时间
     */
    private String reportingWorkTime;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/OptimizeLayoutMapper.java
File was deleted
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/ReportingWorkMapper.java
New file
@@ -0,0 +1,16 @@
package com.mes.pp.mapper;
import com.mes.pp.entity.ReportingWork;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
public interface ReportingWorkMapper extends BaseMapper<ReportingWork> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/request/AwaitingRepairMapper.java
New file
@@ -0,0 +1,16 @@
package com.mes.pp.mapper.request;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.pp.entity.request.AwaitingRepair;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
public interface AwaitingRepairMapper extends BaseMapper<AwaitingRepair> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/request/ReportingDamageMapper.java
New file
@@ -0,0 +1,16 @@
package com.mes.pp.mapper.request;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.pp.entity.request.Reportingdamage;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
public interface ReportingDamageMapper extends BaseMapper<Reportingdamage> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/OptimizeLayoutService.java
File was deleted
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/OptimizeProjectService.java
@@ -33,4 +33,11 @@
     * @return
     */
    boolean overTask(UpPattenUsage sequence, int state);
    /**
     * 获取正在进行中的任务
     *
     * @return
     */
    List<OptimizeProject> getDoingTask();
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/ReportingWorkService.java
New file
@@ -0,0 +1,33 @@
package com.mes.pp.service;
import com.mes.pp.entity.ReportingWork;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.pp.entity.request.AwaitingRepair;
import com.mes.pp.entity.request.Reportingdamage;
import java.util.List;
/**
 * <p>
 *  服务类
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
public interface ReportingWorkService extends IService<ReportingWork> {
     /**
      * 获取顶部扇形图破损加工数量,传入参数:工序,设备,加工时间
      *
      * @return
      */
     List<Reportingdamage> selectDamage(Reportingdamage reportingdamage);
     /**
      * 获取破损未补片的列表
      *
      * @return
      */
     List<AwaitingRepair> selectAwaitingRepair();
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/OptimizeLayoutServiceImpl.java
File was deleted
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/OptimizeProjectServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.base.MPJBaseServiceImpl;
@@ -13,6 +14,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
@@ -64,5 +66,13 @@
        return false;
    }
    @Override
    public List<OptimizeProject> getDoingTask() {
        QueryWrapper<OptimizeProject> wrapper = new QueryWrapper<>();
        wrapper.select("project_no,project_name")
        .eq("state",200);
        return this.list(wrapper);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/ReportingWorkServiceImpl.java
New file
@@ -0,0 +1,54 @@
package com.mes.pp.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mes.pp.entity.ReportingWork;
import com.mes.pp.entity.request.AwaitingRepair;
import com.mes.pp.entity.request.Reportingdamage;
import com.mes.pp.mapper.ReportingWorkMapper;
import com.mes.pp.mapper.request.AwaitingRepairMapper;
import com.mes.pp.mapper.request.ReportingDamageMapper;
import com.mes.pp.service.ReportingWorkService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wu
 * @since 2024-06-26
 */
@Service
@DS("pp")
@Slf4j
public class ReportingWorkServiceImpl extends ServiceImpl<ReportingWorkMapper, ReportingWork> implements ReportingWorkService {
@Autowired
private ReportingDamageMapper reportingDamageMapper;
@Autowired
private AwaitingRepairMapper awaitingRepairMapper;
    @Override
    public List<Reportingdamage> selectDamage(Reportingdamage reportingdamage) {
        QueryWrapper<Reportingdamage>queryWrapper=new QueryWrapper<>();
        queryWrapper.select("this_process,sum(completed_quantity)as completedQuantity,sum(breakage_quantity)as breakageQuantity,device_name ")
                .eq("this_process",reportingdamage.getThisProcess())
                //.eq("device_name",reportingdamage.getDeviceName())
                .ge("reporting_work_time",reportingdamage.getReportingWorkTime())
                .groupBy("this_process");
        return reportingDamageMapper.selectList(queryWrapper);
    }
    @Override
    public List<AwaitingRepair> selectAwaitingRepair() {
        QueryWrapper<AwaitingRepair>queryWrapper=new QueryWrapper<>();
        queryWrapper.select("*");
        return awaitingRepairMapper.selectList(queryWrapper);
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/entity/TemperingGlassInfo.java
@@ -2,6 +2,9 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mes.base.entity.BigStorageCageBaseInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -13,88 +16,92 @@
 * </p>
 *
 * @author zhoush
 * @since 2024-04-07
 * @since 2024-03-27
 */
@ApiModel(description = "<p> 钢化小片信息表 </p>")
@Data
@EqualsAndHashCode(callSuper = false)
public class TemperingGlassInfo implements Serializable {
public class TemperingGlassInfo extends BigStorageCageBaseInfo implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 钢化小片信息表id
     */
    @ApiModelProperty(value = "钢化小片信息表id", position = 2)
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 流程卡
     */
    private String flowcardId;
    @ApiModelProperty(value = "流程卡", position = 4)
    private String flowCardId;
    /**
     * 流程卡玻璃类型
     */
    @ApiModelProperty(value = "流程卡玻璃类型", position = 5)
    private Integer glassType;
    /**
     * 宽
     */
    private Double width;
    /**
     * 高
     */
    private Double height;
    @ApiModelProperty(value = "高", position = 7)
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    @ApiModelProperty(value = "厚度", position = 8)
    private double thickness;
    /**
     * 膜系
     */
    private Integer filmsid;
    @ApiModelProperty(value = "膜系", position = 9)
    private String filmsid;
    /**
     * 钢化是否接受横放
     */
    @ApiModelProperty(value = "钢化是否接受横放", position = 10)
    private Integer ishorizontal;
    /**
     * 钢化版图id
     */
    @ApiModelProperty(value = "钢化版图id", position = 11)
    private Integer temperingLayoutId;
    /**
     * 钢化版图片序
     */
    @ApiModelProperty(value = "钢化版图片序", position = 12)
    private Integer temperingFeedSequence;
    /**
     * x坐标
     */
    @ApiModelProperty(value = "x坐标", position = 13)
    private Integer xCoordinate;
    /**
     * y坐标
     */
    @ApiModelProperty(value = "y坐标", position = 14)
    private Integer yCoordinate;
    /**
     * 旋转角度(逆时针)
     */
    @ApiModelProperty(value = "旋转角度(逆时针)", position = 15)
    private Integer angle;
    /**
     * 状态
     */
    @ApiModelProperty(value = "状态", position = 16)
    private Integer state;
    /**
     * 格子号
     */
    private Integer slot;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/mapper/TemperingGlassInfoMapper.java
@@ -3,6 +3,9 @@
import com.baomidou.dynamic.datasource.annotation.DS;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -12,7 +15,9 @@
 * @author zhoush
 * @since 2024-04-07
 */
@DS("salve_hangzhoumes")
@DS("salve_hangzhoumes_1")
public interface TemperingGlassInfoMapper extends MPJBaseMapper<TemperingGlassInfo> {
    boolean saveBatch(@Param(value = "list") List<TemperingGlassInfo> list);
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/tools/CodeGet.java
@@ -22,7 +22,7 @@
        // 2、全局配置
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir("D:\\Documents\\hangzhoumesParent4\\");
        gc.setOutputDir("D:\\Documents\\hangzhoumesParent5\\");
        gc.setServiceName("%sService");    //去掉Service接口的首字母I
        gc.setAuthor("wu");
@@ -41,7 +41,7 @@
        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.mes");
        pc.setModuleName("glassinfo"); //模块名
        pc.setModuleName("work_assignment"); //模块名
        pc.setController("controller");
        pc.setService("service");
        pc.setMapper("mapper");
@@ -50,7 +50,7 @@
        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("glass_info");
        strategy.setInclude("work_assignment");
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
hangzhoumesParent/common/servicebase/src/main/java/com/mes/tools/DatabaseDesignDocUtil.java
@@ -31,9 +31,9 @@
    public static void documentGeneration() {
        //数据源
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
        hikariConfig.setJdbcUrl("jdbc:mysql://10.153.19.150:3306/hangzhoumes" + "?serverTimezone=GMT%2B8");
        hikariConfig.setUsername("root");
        hikariConfig.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        hikariConfig.setJdbcUrl("jdbc:sqlserver://10.153.19.150:1433;databasename=hangzhoumes");
        hikariConfig.setUsername("sa");
        hikariConfig.setPassword("beibo.123/");
        //设置可以获取tables remarks信息
        hikariConfig.addDataSourceProperty("useInformationSchema", "true");
@@ -43,7 +43,7 @@
        //生成配置
        EngineConfig engineConfig = EngineConfig.builder()
                //生成文件路径
                .fileOutputDir("E:\\项目\\项目文档\\杭州利来1")
                .fileOutputDir("E:\\项目\\项目文档\\杭州利来2")
                //打开目录
                .openOutputDir(true)
                //文件类型
hangzhoumesParent/common/servicebase/src/main/java/com/mes/uppattenusage/entity/UpPattenUsage.java
@@ -40,17 +40,17 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 原片版图片序
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/controller/WorkAssignmentController.java
New file
@@ -0,0 +1,36 @@
package com.mes.work_assignment.controller;
import cn.hutool.core.date.DateTime;
import com.mes.damage.service.DamageService;
import com.mes.utils.Result;
import com.mes.work_assignment.service.WorkAssignmentService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wu
 * @since 2024-07-01
 */
@RestController
@RequestMapping("/work_assignment/work-assignment")
public class WorkAssignmentController {
    @Autowired
    private WorkAssignmentService workAssignmentService;
    @ApiOperation("报工数据查询")
    @GetMapping("/selectWorkAssignment")
    public Result selectDamage(int line,String workingProcedure) {
        return Result.build(200,"查询成功",workAssignmentService.selectWorkAssignment(line,workingProcedure));
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/entity/WorkAssignment.java
New file
@@ -0,0 +1,44 @@
package com.mes.work_assignment.entity;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 *
 * </p>
 *
 * @author wu
 * @since 2024-07-01
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class WorkAssignment implements Serializable {
    private static final long serialVersionUID = 1L;
      private Integer id;
    /**
     * 线路
     */
    private Integer line;
    /**
     * 工序
     */
    private String workProcesses;
    /**
     * 班组名称
     */
    private String teamsGroupsName;
    /**
     * 设备名称
     */
    private String deviceName;
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/mapper/WorkAssignmentMapper.java
New file
@@ -0,0 +1,16 @@
package com.mes.work_assignment.mapper;
import com.mes.work_assignment.entity.WorkAssignment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wu
 * @since 2024-07-01
 */
public interface WorkAssignmentMapper extends BaseMapper<WorkAssignment> {
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/mapper/xml/WorkAssignmentMapper.xml
New file
@@ -0,0 +1,5 @@
<?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 namespace="com.mes.work_assignment.mapper.WorkAssignmentMapper">
</mapper>
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/service/WorkAssignmentService.java
New file
@@ -0,0 +1,17 @@
package com.mes.work_assignment.service;
import com.mes.work_assignment.entity.WorkAssignment;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 *  服务类
 * </p>
 *
 * @author wu
 * @since 2024-07-01
 */
public interface WorkAssignmentService extends IService<WorkAssignment> {
    WorkAssignment selectWorkAssignment(int line, String workingProcedure);
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/work_assignment/service/impl/WorkAssignmentServiceImpl.java
New file
@@ -0,0 +1,35 @@
package com.mes.work_assignment.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.work_assignment.entity.WorkAssignment;
import com.mes.work_assignment.mapper.WorkAssignmentMapper;
import com.mes.work_assignment.service.WorkAssignmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wu
 * @since 2024-07-01
 */
@Service
public class WorkAssignmentServiceImpl extends ServiceImpl<WorkAssignmentMapper, WorkAssignment> implements WorkAssignmentService {
    /**
     * 查询当前值班信息
     * @param line
     * @param workingProcedure
     * @return
     */
    @Override
    public WorkAssignment selectWorkAssignment(int line, String workingProcedure){
        LambdaQueryWrapper<WorkAssignment> workAssignmentSelectWrapper=new LambdaQueryWrapper<>();
        workAssignmentSelectWrapper
                .eq(WorkAssignment::getLine,line)
                .eq(WorkAssignment::getWorkProcesses,workingProcedure);
        return baseMapper.selectOne(workAssignmentSelectWrapper);
    }
}
hangzhoumesParent/common/servicebase/src/main/resources/mapper/TemperingGlassInfoMapper.xml
New file
@@ -0,0 +1,16 @@
<?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 namespace="com.mes.temperingglass.mapper.TemperingGlassInfoMapper">
    <insert id="saveBatch">
        INSERT INTO tempering_glass_info (glass_id, flow_card_id, glass_type, width, height, thickness, filmsid,
        ishorizontal, tempering_layout_id,
        tempering_feed_sequence, x_coordinate, y_coordinate, angle, state, slot ) VALUES
        <foreach collection="list" item="item" separator=",">
            (#{item.glassId}, #{item.flowCardId}, #{item.glassType}, #{item.width}, #{item.height}, #{item.thickness},
            #{item.filmsid},#{item.ishorizontal},
            #{item.temperingLayoutId}, #{item.temperingFeedSequence}, #{item.xCoordinate}, #{item.yCoordinate},
            #{item.angle}, #{item.state}, #{item.slot})
        </foreach>
    </insert>
</mapper>
hangzhoumesParent/common/springsecurity/pom.xml
@@ -23,6 +23,7 @@
            <artifactId>servicebase</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- Spring Security依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/controller/SysMenuController.java
@@ -29,15 +29,20 @@
    @PostMapping("/save")
//    @PreAuthorize("hasAuthority('sys:menu:save')")
    public Result save(@Validated @RequestBody SysMenu sysMenu) {
        return Result.success(sysMenuService.save(sysMenu));
        sysMenuService.save(sysMenu);
        GeneralRequest request=new GeneralRequest();
        return Result.success(sysMenuService.getMenuTree(request));
    }
    @ApiOperation("修改菜单信息")
    @PostMapping("/updateMenu")
//    @PreAuthorize("hasAuthority('sys:menu:update')")
    public Result updateMenu(@Validated @RequestBody SysMenu sysMenu) {
    public Result<List<SysMenu>> updateMenu(@Validated @RequestBody SysMenu sysMenu) {
        //return Result.success(sysMenu);
        sysMenuService.updateMenu(sysMenu);
        return Result.success(sysMenu);
        GeneralRequest request=new GeneralRequest();
        return Result.build(200,"修改成功",sysMenuService.getMenuTree(request));
    }
    @ApiOperation("获取用户有权限的所有菜单")
@@ -62,8 +67,9 @@
    @ApiOperation("删除菜单")
    @PostMapping("/deleteMenu")
//    @PreAuthorize("hasAuthority('sys:menu:delete')")
    public Result<String> deleteMenu(Long menuId) {
        return Result.success(sysMenuService.deleteMenu(menuId));
    public Result<List<SysMenu>> deleteMenu(Long menuId) {
        GeneralRequest request=new GeneralRequest();
        return Result.build(200, sysMenuService.deleteMenu(menuId),sysMenuService.getMenuTree(request));
    }
    @ApiOperation("批量删除菜单")
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/controller/SysRoleController.java
@@ -57,7 +57,7 @@
//    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Transactional
    public Result<String> deleteRole(@RequestBody List<Long> ids) {
        return Result.success(sysRoleService.deleteRole(ids));
        return Result.build(200,"删除成功",sysRoleService.deleteRole(ids));
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleServiceImpl.java
@@ -19,6 +19,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
@@ -102,7 +103,14 @@
     * @return
     */
    private String saveRoleMenu(Long roleId, List<SysMenu> menuList) {
        log.info("配置角色菜单关心");
        log.info("配置角色菜单关系");
        if (CollectionUtils.isEmpty(menuList)) {
            // 先删除原来的记录,再保存新的
            sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
            // 删除缓存
            sysUserService.clearUserAuthorityInfoByRoleId(roleId);
            return "success";
        }
        List<SysRoleMenu> roleMenuList = menuList.stream().map(menu -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
@@ -110,12 +118,9 @@
            return roleMenu;
        }).collect(Collectors.toList());
        log.info("清空角色权限表中该角色信息");
        // 先删除原来的记录,再保存新的
        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
        sysRoleMenuService.saveBatch(roleMenuList);
        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return "success";
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/userinfo/controller/SysUserController.java
@@ -60,8 +60,13 @@
    @ApiOperation("更新用户信息")
    @PostMapping("/updateUser")
//    @PreAuthorize("hasAuthority('sys:user:update')")
    public Result<SysUserVO> updateUser(@Validated @RequestBody SysUserVO sysUser) {
        return Result.success(sysUserService.updateUser(sysUser));
    public Result<List<SysUserVO>> updateUser(@Validated @RequestBody SysUserVO sysUser) {
        //return Result.success(sysUserService.updateUser(sysUser));
        sysUserService.updateUser(sysUser);
        GeneralRequest request=new GeneralRequest();
        request.setKey("");
        return Result.success(sysUserService.listByUserName(request));
        //更改了修改之后返回所有用户列表
    }
    @ApiOperation("重置密码")
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/userinfo/service/impl/SysUserServiceImpl.java
@@ -19,6 +19,7 @@
import com.mes.userinfo.entity.SysUserRole;
import com.mes.userinfo.entity.vo.SysUserVO;
import com.mes.userinfo.mapper.SysUserMapper;
import com.mes.userinfo.mapper.SysUserRoleMapper;
import com.mes.userinfo.service.SysUserRoleService;
import com.mes.userinfo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
@@ -71,6 +72,8 @@
    @Resource
    BCryptPasswordEncoder passwordEncoder;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Override
    public Map<String, String> login(SysUser user) {
@@ -125,10 +128,12 @@
        this.updateById(sysUser);
        log.info("删除用户角色信息");
        List<Long> roleIds = user.getRoleList().stream().map(SysRole::getId).collect(Collectors.toList());
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, sysUser.getId()).in(CollectionUtil.isNotEmpty(roleIds), SysUserRole::getRoleId, roleIds));
        log.info("保存用户角色信息");
        saveUserRole(user.getRoleList(), sysUser.getId());
//        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
//                .eq(SysUserRole::getUserId, sysUser.getId()).in(CollectionUtil.isNotEmpty(roleIds), SysUserRole::getRoleId, roleIds));
        SysUserRole sysUserRole = new SysUserRole(sysUser.getId(),roleIds.get(0));
        sysUserRoleMapper.updateById(sysUserRole);
//        log.info("保存用户角色信息");
//        saveUserRole(user.getRoleList(), sysUser.getId());
        return user;
    }
hangzhoumesParent/moduleService/CacheGlassModule/pom.xml
@@ -17,11 +17,7 @@
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.samba.jcifs</groupId>
            <artifactId>jcifs</artifactId>
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/entity/EdgStorageCage.java
@@ -40,7 +40,7 @@
    /**
     * 启用状态
     */
    private String enableState;
    private Integer enableState;
    /**
     * 剩余
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/entity/EdgStorageCageDetails.java
@@ -29,7 +29,7 @@
    private Long id;
    /**
     * 设备id
     * 工程id
     */
    private String engineerId;
@@ -66,27 +66,27 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 磨前宽
     */
    private Double edgWidth;
    private double edgWidth;
    /**
     * 磨前高
     */
    private Double edgHeight;
    private double edgHeight;
    /**
     * 钢化版图id
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/service/EdgStorageCageService.java
@@ -19,6 +19,7 @@
    /**
     * 查询笼内离指定格子最近空格
     * flag :是否为直通
     *
     * @return
     */
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgstoragecage/service/impl/EdgStorageCageDetailsServiceImpl.java
@@ -24,6 +24,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.print.attribute.standard.MediaSize;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -90,7 +91,8 @@
    public List<Map<String, Object>> selectCutTerritory() {
        List<UpPattenUsage> upPattenUsage = upPattenUsageMapper.selectList(new MPJLambdaWrapper<UpPattenUsage>()
                .selectAll(UpPattenUsage.class)
                .eq(UpPattenUsage::getState, 1).or().eq(UpPattenUsage::getState, 0).orderByDesc(UpPattenUsage::getState));
                .orderByDesc(UpPattenUsage::getState)
                .orderByDesc(UpPattenUsage::getId));
        if (!upPattenUsage.isEmpty()) {
            UpPattenUsage upPattenUsage1 = upPattenUsage.get(0);
            List<Map<String, Object>> cutTerritorys=optimizeDetailMapper.selectJoinMaps(JoinWrappers.lambda(OptimizeDetail.class)
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/CacheGlassTask.java
@@ -72,7 +72,7 @@
    @Value("${mes.secondLength}")
    private String secondLength;
//    @Scheduled(fixedDelay = 5000000)
    @Scheduled(fixedDelay = 1000)
    public void plcHomeEdgTask() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
@@ -93,7 +93,7 @@
                return;
            }
            log.info("2、获取到的请求字为0,将确认字改为0");
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, (short) 0);
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 0);
            return;
        }
        if (!"0".equals(confirmationWrodValue)) {
@@ -169,7 +169,7 @@
        boolean taskCache = saveTaskCache(details.getGlassId(), 0, nearestEmpty.getSlot(), Const.GLASS_CACHE_TYPE_IN);
        log.info("5、生成进片任务信息存入任务表是否完成:{}", taskCache);
        S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, (short) 1);
        S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
        log.info("6、发送确认字完成");
@@ -182,8 +182,8 @@
     * @return
     */
    public GlassInfo queryAndChangeGlass(String glassId) {
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId)
                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");
        //按照玻璃尺寸
        LambdaQueryWrapper<GlassInfo> queryWrapper = new LambdaQueryWrapper<GlassInfo>()
@@ -277,8 +277,8 @@
                    List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(wrapper);
                    if (CollectionUtil.isEmpty(list)) {
                        MPJQueryWrapper<GlassInfo> queryWrapper = new MPJQueryWrapper<GlassInfo>()
                                .selectAll(GlassInfo.class).eq("t.glass_id", glassId)
                                .inSql("t.engineer_id", "select engineer_id from engineering where state = 1");
                                .selectAll(GlassInfo.class).eq("t.glass_id", glassId);
//                                .inSql("t.engineer_id", "select engineer_id from engineering where state = 1");
                        if (endcell == Const.A10_OUT_TARGET_POSITION) {
                            queryWrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                                    "case when width < height then width else height end as second_length from glass_info) t1 " +
@@ -347,8 +347,8 @@
        //todo: 获取正在执行的工程信息
        if (StringUtils.isNotBlank(glassId)) {
            GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                    .eq(GlassInfo::getGlassId, glassId)
                    .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
                    .eq(GlassInfo::getGlassId, glassId));
//                    .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
            EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
            BeanUtils.copyProperties(one, resultDetails);
            glassList.add(resultDetails);
@@ -387,7 +387,7 @@
     * @param width
     * @param height
     */
    private EdgStorageCageDetails queryMinGlass(Double width, Double height, String glassId) {
    private EdgStorageCageDetails queryMinGlass(double width, double height, String glassId) {
        //获取表内版图id最小的玻璃信息
        EdgStorageCageDetails glassDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getState, 100)
@@ -400,8 +400,8 @@
            return glassDetails;
        }
        GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                .eq(GlassInfo::getGlassId, glassId)
                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1")
                        .eq(GlassInfo::getGlassId, glassId)
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1")
        );
        EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
        BeanUtils.copyProperties(one, resultDetails);
@@ -451,7 +451,8 @@
            return null;
        }
        return edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId())
                .inSql(EdgStorageCageDetails::getEngineerId, "select engineer_id from engineering where state = 1").last(" limit 1 "));
//                .inSql(EdgStorageCageDetails::getEngineerId, "select engineer_id from engineering where state = 1")
                .last(" limit 1 "));
    }
    /**
@@ -466,10 +467,10 @@
     */
    private Integer queryLineByGlassInfo(EdgStorageCageDetails a08EdgStorageCageDetails, EdgStorageCageDetails a10EdgStorageCageDetails,
                                         EdgStorageCageDetails glassInfo, int out08Glassstate, int out10Glassstate) {
        boolean b08 = a08EdgStorageCageDetails != null && a08EdgStorageCageDetails.getHeight().equals(glassInfo.getHeight())
                && a08EdgStorageCageDetails.getWidth().equals(glassInfo.getWidth());
        boolean b10 = a10EdgStorageCageDetails != null && a10EdgStorageCageDetails.getHeight().equals(glassInfo.getHeight())
                && a10EdgStorageCageDetails.getWidth().equals(glassInfo.getWidth());
        boolean b08 = a08EdgStorageCageDetails != null && a08EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
                && a08EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
        boolean b10 = a10EdgStorageCageDetails != null && a10EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
                && a10EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
        //存在出片任务 07为空
        if (b10) {
            return out10Glassstate == 2 ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
@@ -507,16 +508,16 @@
        //获取宽高拍第一的玻璃信息
        EdgStorageCageDetails firstSize = list.get(0);
        Integer firstCount = firstSize.getCount();
        Double firstWidth = firstSize.getWidth();
        Double firstHeight = firstSize.getHeight();
        double firstWidth = firstSize.getWidth();
        double firstHeight = firstSize.getHeight();
        if (list.size() == 1) {
            return queryMinGlass(firstWidth, firstHeight, glassId);
        }
        //获取宽高拍第二的玻璃信息
        EdgStorageCageDetails secondSize = list.get(1);
        Integer secondCount = secondSize.getCount();
        Double secondWidth = secondSize.getWidth();
        Double secondHeight = secondSize.getHeight();
        double secondWidth = secondSize.getWidth();
        double secondHeight = secondSize.getHeight();
        //获取数量前2的玻璃数量比例
        Integer mix = firstCount / secondCount;
        log.info("获取玻璃数量前2的玻璃占比为:{}", mix);
@@ -536,7 +537,7 @@
            EdgStorageCageDetails outGlassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId()));
            log.info("{}线有出片任务信息,任务信息为{},玻璃信息为{}", endcell, taskCache, outGlassInfo);
            if (outGlassInfo.getWidth().equals(firstWidth) && outGlassInfo.getHeight().equals(firstHeight)) {
            if (outGlassInfo.getWidth() == firstWidth && outGlassInfo.getHeight() == firstHeight) {
                log.info("数量最多的宽{}高{}和{}线任务的宽{}高{}相同,出数量排第二的玻璃,宽{}高{}",
                        firstWidth, firstHeight, endcell, outGlassInfo.getWidth(), outGlassInfo.getHeight(), secondWidth, secondHeight);
                return queryMinGlass(secondWidth, secondHeight, glassId);
@@ -588,7 +589,7 @@
            }
            boolean glassSizeStatus = saveGlassSize(glassInfo);
            log.info("7、添加出片玻璃尺寸信息到磨边前玻璃表是否完成:{}", glassSizeStatus);
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, (short) 1);
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
            log.info("8、发送确认字已完成");
            return Boolean.TRUE;
        }
@@ -631,23 +632,24 @@
        return edgGlassTaskInfoService.save(edgGlassTaskInfo);
    }
    /**
     * 当前切割版图信息 +磨边任务+磨边前 缓存内信息
     *
     * @param
     * @return
     */
    @Scheduled(fixedDelay = 1000)
    public void currentCutTerritory(){
    public void CacheGlassTasks() {
        JSONObject jsonObject = new JSONObject();
        //识别摆片
        List<Map<String, Object>> currentCutTerritorys = edgStorageCageDetailsService.selectCutTerritory();
        jsonObject.append("currentCutTerritory", currentCutTerritorys);
        List<Map<String,Object>> EdgTasks1 = taskCacheService.selectEdgInfo("2001");
        List<Map<String,Object>> EdgTasks2 = taskCacheService.selectEdgInfo("2002");
        //磨边信息
        List<Map<String, Object>> EdgTasks1 = taskCacheService.selectEdgInfo("2001");
        List<Map<String, Object>> EdgTasks2 = taskCacheService.selectEdgInfo("2002");
        jsonObject.append("EdgTasks1", EdgTasks1);
        jsonObject.append("EdgTasks2", EdgTasks2);
        List<Map<String, Object>> EdgStorageCageinfos=edgStorageCageService.selectEdgStorageCages();
        //卧室缓存笼内信息
        List<Map<String, Object>> EdgStorageCageinfos = edgStorageCageService.selectEdgStorageCages();
        jsonObject.append("EdgStorageCageinfos", EdgStorageCageinfos);
        ArrayList<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("cacheGlass");
        if (sendwServer != null) {
            for (WebSocketServer webserver : sendwServer) {
@@ -664,7 +666,6 @@
            }
        }
    }
hangzhoumesParent/moduleService/CacheGlassModule/src/main/resources/application-prod.yml
@@ -15,10 +15,10 @@
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        salve_hangzhoumes:
            url: jdbc:sqlserver://10.153.19.150:3306;databasename=hangzhoumes
            username: sa
            password: beibo.123/
            driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
          url: jdbc:sqlserver://10.153.19.150:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/CacheVerticalGlassModule/pom.xml
@@ -17,11 +17,6 @@
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>
<properties>
    <maven.compiler.source>8</maven.compiler.source>
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageController.java
@@ -1,7 +1,4 @@
package com.mes.bigstorage.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.utils.Result;
import io.swagger.annotations.Api;
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageDetailsController.java
@@ -1,15 +1,15 @@
package com.mes.bigstorage.controller;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
 * <p>
@@ -26,48 +26,52 @@
    @Autowired
    private BigStorageCageDetailsService bigStorageCageDetailsService;
    @Autowired
    private BigStorageCageService bigStorageCageService;
    @ApiOperation("玻璃详情查询")
    @PostMapping("/selectBigStorageCageDetails")
    public Result selectBigStorageCageDetails(String glassId) {
        BigStorageCageDetails bigStorageCageDetails=bigStorageCageDetailsService.selectBigStorageCageDetails(glassId);
    public Result selectBigStorageCageDetails(@RequestBody Map map) {
        List<BigStorageCageDetails> bigStorageCageDetails=bigStorageCageDetailsService.selectBigStorageCageDetails(map.get("glassId").toString());
        return Result.build(200,"查询成功",bigStorageCageDetails);
    }
    @ApiOperation("理片笼详情添加")
    @PostMapping("/insertBigStorageCageDetails")
    public Result insertBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
    public Result insertBigStorageCageDetails(@RequestBody BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetailsService.insertBigStorageCageDetails(bigStorageCageDetails);
        return Result.build(200,"添加成功",1);
        return Result.build(200,"添加成功",bigStorageCageService.querybigStorageCageDetail(0));
    }
    @ApiOperation("理片笼详情删除")
    @PostMapping("/deleteBigStorageCageDetails")
    public Result deleteBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
    public Result deleteBigStorageCageDetails(@RequestBody BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetailsService.deleteBigStorageCageDetails(bigStorageCageDetails);
        return Result.build(200,"删除成功",1);
        return Result.build(200,"删除成功",bigStorageCageService.querybigStorageCageDetail(0));
    }
    @ApiOperation("理片笼任务破损")
    @ApiOperation("理片笼任务破损0/拿走1")
    @PostMapping("/damageBigStorageCageDetails")
    public Result damageBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetailsService.damageBigStorageCageDetails(bigStorageCageDetails.getGlassId());
        return Result.build(200,"破损成功",1);
    public Result damageBigStorageCageDetails(@RequestBody BigStorageCageDetails bigStorageCageDetails,int status) {
        bigStorageCageDetailsService.damageBigStorageCageDetails(bigStorageCageDetails.getGlassId(),status);
        return Result.build(200,"破损/拿走成功",1);
    }
    @ApiOperation("理片笼任务完成")
    @PostMapping("/finishBigStorageCageDetails")
    public Result finishBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
    public Result finishBigStorageCageDetails(@RequestBody BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetailsService.finishBigStorageCageDetails(bigStorageCageDetails);
        return Result.build(200,"破损成功",1);
        return Result.build(200,"任务完成成功",1);
    }
    @ApiOperation("理片笼任务出片")
    @PostMapping("/outBigStorageCageDetails")
    public Result outBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
    public Result outBigStorageCageDetails(@RequestBody BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetailsService.outBigStorageCageDetails(bigStorageCageDetails);
        return Result.build(200,"破损成功",1);
        return Result.build(200,"出片添加成功",1);
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageCage.java
@@ -29,8 +29,8 @@
    /**
     * 大理片笼表id
     */
      @ApiModelProperty(value = "大理片笼表id", position = 2)
      @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "大理片笼表id", position = 2)
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageCageDetails.java
@@ -3,16 +3,15 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
 * <p>
@@ -22,19 +21,18 @@
 * @author zhoush
 * @since 2024-03-27
 */
@ApiModel(description = "<p> </p>")
@Api(description = "大理片笼详情")
@Data
@EqualsAndHashCode(callSuper = false)
public class BigStorageCageDetails implements Serializable {
public class BigStorageCageDetails extends BigStorageCageBaseInfo implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 大理片笼详情表id
     */
      @ApiModelProperty(value = "大理片笼详情表id", position = 2)
      @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "大理片笼详情表id", position = 2)
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
@@ -43,17 +41,6 @@
    @ApiModelProperty(value = "设备id", position = 3)
    private Integer deviceId;
    /**
     * 栅格号
     */
    @ApiModelProperty(value = "栅格号", position = 4)
    private Integer slot;
    /**
     * 玻璃id
     */
    @ApiModelProperty(value = "玻璃id", position = 5)
    private String glassId;
    /**
     * 小片在格内的顺序
@@ -74,22 +61,16 @@
    private Integer glassType;
    /**
     * 宽
     */
    @ApiModelProperty(value = "宽", position = 9)
    private Double width;
    /**
     * 高
     */
    @ApiModelProperty(value = "高", position = 10)
    private Double height;
    private double height;
    /**
     * 厚度
     */
    @ApiModelProperty(value = "厚度", position = 11)
    private Double thickness;
    private double thickness;
    /**
     * 钢化版图id
@@ -116,6 +97,12 @@
    private Integer gap;
    /**
     * 工程号
     */
    @ApiModelProperty(value = "工程号")
    private String engineerId;
    /**
     * 进片任务
     */
    @ApiModelProperty(value = "进片任务", position = 16)
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/BigStorageDTO.java
@@ -9,6 +9,17 @@
 */
@Data
public class BigStorageDTO {
    /**
     * 格子号
     */
    private Integer slot;
    /**
     * 剩余宽度
     */
    private Integer width;
    /**
     * 玻璃数量
     */
    private Integer glassCount;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/dto/SlotSequenceDTO.java
New file
@@ -0,0 +1,38 @@
package com.mes.bigstorage.entity.dto;
import lombok.Data;
/**
 * @Author : zhoush
 * @Date: 2024/6/13 15:51
 * @Description:
 */
@Data
public class SlotSequenceDTO {
    /**
     * 钢化版图id
     */
    private String engineerId;
    /**
     * 钢化版图id
     */
    private Integer temperingLayoutId;
    /**
     * 大理片详情中格子号
     */
    private Integer slot;
    /**
     * 格子内的最大序号
     */
    private Integer maxSequence;
    /**
     * 格子内的最小序号
     */
    private Integer minSequence;
    /**
     * 格子剩余宽度
     */
    private Integer remainWidth;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/dto/TemperingLayoutDTO.java
New file
@@ -0,0 +1,30 @@
package com.mes.bigstorage.entity.dto;
import lombok.Data;
/**
 * @Author : zhoush
 * @Date: 2024/6/13 15:51
 * @Description:
 */
@Data
public class TemperingLayoutDTO {
    /**
     * 钢化版图id
     */
    private String engineerId;
    /**
     * 钢化版图id
     */
    private Integer temperingLayoutId;
    /**
     * 当前版图数量
     */
    private Integer count;
    /**
     * 当前版图占用格子数量
     */
    private Integer slotCount;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/mapper/BigStorageCageDetailsMapper.java
@@ -1,9 +1,12 @@
package com.mes.bigstorage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import feign.Param;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
@@ -16,4 +19,20 @@
 */
public interface BigStorageCageDetailsMapper extends MPJBaseMapper<BigStorageCageDetails> {
    /**
     * 获取钢化版图已经到齐的工程号及版图id
     *
     * @return
     */
    TemperingLayoutDTO temperingIsAll();
    /**
     * 获取每个钢化版图占用的格子数量
     *
     * @return
     */
    TemperingLayoutDTO queryTemperingOccupySlot(@Param(value = "count") int count);
    List<SlotSequenceDTO> queryGlassMaxAndMin(@Param(value = "engineerId") String engineerId, @Param(value = "temperingLayoutId") Integer temperingLayoutId);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageDetailsService.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.glassinfo.entity.GlassInfo;
import java.util.List;
@@ -23,9 +25,9 @@
    void deleteBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails);
    void damageBigStorageCageDetails(String glassId);
    void damageBigStorageCageDetails(String glassId,int status);
    BigStorageCageDetails selectBigStorageCageDetails(String glassId);
    List<BigStorageCageDetails> selectBigStorageCageDetails(String glassId);
    void insertBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails);
@@ -39,4 +41,27 @@
     * @param glassInfo
     */
    BigStorageDTO queryTargetSlotByTempering(GlassInfo glassInfo);
    /**
     * 获取钢化版图已经到齐的工程号及版图id
     *
     * @return
     */
    TemperingLayoutDTO temperingIsAll();
    /**
     * 获取每个钢化版图占用的格子数量
     *
     * @return
     */
    TemperingLayoutDTO queryTemperingOccupySlot();
    /**
     * 获取版图每个格子的最大最小序号
     *
     * @param engineerId
     * @param temperingLayoutId
     * @return
     */
    List<SlotSequenceDTO> queryGlassMaxAndMin(String engineerId, Integer temperingLayoutId);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageService.java
@@ -26,7 +26,9 @@
    List<BigStorageCage> querybigStorageCageDetail(int deviceId);
    Map<Integer, List<BigStorageCage>> querybigStorageCageDetail();
    List<Map<String, Object>> selectBigStorageCageUsage();
    void updateStorageCageDisabled(int slot,int enableState);
    void updateStorageCageDisabled(int slot, int enableState);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java
@@ -7,6 +7,8 @@
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.mapper.BigStorageCageDetailsMapper;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
@@ -20,9 +22,11 @@
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.mapper.TemperingGlassInfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -49,46 +53,57 @@
    @Resource
    private GlassInfoMapper glassInfoMapper;
    @Value("${mes.minCount}")
    private int minCount;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.galssGap}")
    private Integer galssGap;
    /**
     * 查询进/出片任务
     */
    @Override
    public List<BigStorageCageDetails> selectTask(int taskType) {
        if (taskType == 1) {
            //进片任务数据
            LambdaQueryWrapper<BigStorageCageDetails> feedWrapper = new LambdaQueryWrapper<>();
            feedWrapper.eq(BigStorageCageDetails::getState, 1)
                    .or()
                    .eq(BigStorageCageDetails::getState, 2);
            List<BigStorageCageDetails> bigStorageCageDetailsList = baseMapper.selectList(feedWrapper);
            List<BigStorageCageFeedTask> bigStorageCageFeedTaskList = bigStorageCageFeedTaskMapper.selectList(null);
            Map<String, BigStorageCageFeedTask> listMap = bigStorageCageFeedTaskList.stream()
                    .collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId, task -> task));
            for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList) {
                BigStorageCageFeedTask bigStorageCageFeedTask = listMap.get(bigStorageCageDetails.getGlassId());
                bigStorageCageDetails.setBigStorageCageFeedTask(bigStorageCageFeedTask);
            }
            return bigStorageCageDetailsList;
        } else {
            //出片任务数据
            LambdaQueryWrapper<BigStorageCageDetails> outWrapper = new LambdaQueryWrapper<>();
            outWrapper.eq(BigStorageCageDetails::getState, 3)
                    .or()
                    .eq(BigStorageCageDetails::getState, 4);
            List<BigStorageCageDetails> bigStorageCageDetailsList = baseMapper.selectList(outWrapper);
            List<BigStorageCageOutTask> bigStorageCageOutTaskList = bigStorageCageOutTaskMapper.selectList(null);
            Map<String, BigStorageCageOutTask> listMap = bigStorageCageOutTaskList.stream()
                    .collect(Collectors.toMap(BigStorageCageOutTask::getGlassId, task -> task));
            for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList) {
                BigStorageCageOutTask bigStorageCageOutTask = listMap.get(bigStorageCageDetails.getGlassId());
                bigStorageCageDetails.setBigStorageCageOutTask(bigStorageCageOutTask);
            }
            return bigStorageCageDetailsList;
        }
        return null;
//        if (taskType == 1) {
//            //进片任务数据
//            LambdaQueryWrapper<BigStorageCageDetails> feedWrapper = new LambdaQueryWrapper<>();
//            feedWrapper.eq(BigStorageCageDetails::getState, Const.BIG_STORAGE_IN);
//            List<BigStorageCageDetails> bigStorageCageDetailsList = baseMapper.selectList(feedWrapper);
//
//            LambdaQueryWrapper<BigStorageCageFeedTask> feedTaskWrapper = new LambdaQueryWrapper<>();
//            feedTaskWrapper.lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT);
//            List<BigStorageCageFeedTask> bigStorageCageFeedTaskList = bigStorageCageFeedTaskMapper.selectList(feedTaskWrapper);
//
//            Map<String, BigStorageCageFeedTask> listMap = bigStorageCageFeedTaskList.stream()
//                    .collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId, task -> task));
//
//            for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList) {
//                BigStorageCageFeedTask bigStorageCageFeedTask = listMap.get(bigStorageCageDetails.getGlassId());
//                bigStorageCageDetails.setBigStorageCageFeedTask(bigStorageCageFeedTask);
//            }
//            return bigStorageCageDetailsList;
//        } else {
//            //出片任务数据
//            LambdaQueryWrapper<BigStorageCageDetails> outWrapper = new LambdaQueryWrapper<>();
//            outWrapper.eq(BigStorageCageDetails::getState, Const.BIG_STORAGE_OUT);
//            List<BigStorageCageDetails> bigStorageCageDetailsList = baseMapper.selectList(outWrapper);
//
//            LambdaQueryWrapper<BigStorageCageOutTask> outTaskWrapper = new LambdaQueryWrapper<>();
//            outTaskWrapper.lt(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_SUCCESS);
//            List<BigStorageCageOutTask> bigStorageCageOutTaskList = bigStorageCageOutTaskMapper.selectList(outTaskWrapper);
//
//            Map<String, BigStorageCageOutTask> listMap = bigStorageCageOutTaskList.stream()
//                    .collect(Collectors.toMap(BigStorageCageOutTask::getGlassId, task -> task));
//            for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList) {
//                BigStorageCageOutTask bigStorageCageOutTask = listMap.get(bigStorageCageDetails.getGlassId());
//                bigStorageCageDetails.setBigStorageCageOutTask(bigStorageCageOutTask);
//            }
//            return bigStorageCageDetailsList;
//        }
    }
    /**
@@ -116,7 +131,7 @@
        for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList
        ) {
            if (bigStorageCageDetails.getBigStorageCageFeedTask().getTaskState() == 0) {
                carWidth -= Integer.parseInt(bigStorageCageDetails.getWidth().toString()) + bigStorageCageDetails.getGap();
                carWidth = carWidth - bigStorageCageDetails.getWidth() - galssGap;
            }
        }
        return carWidth;
@@ -133,7 +148,8 @@
    //理片笼详情破损
    @Override
    public void damageBigStorageCageDetails(String glassId) {
    public void damageBigStorageCageDetails(String glassId, int status) {
        LambdaQueryWrapper<TemperingGlassInfo> temperingGlassInfoWrapper = new LambdaQueryWrapper<>();
        temperingGlassInfoWrapper.eq(TemperingGlassInfo::getGlassId, glassId);
        TemperingGlassInfo temperingGlassInfo = temperingGlassInfoMapper.selectOne(temperingGlassInfoWrapper);
@@ -142,13 +158,20 @@
        bigStorageCageDetailsWrapper.eq(BigStorageCageDetails::getGlassId, glassId);
        BigStorageCageDetails bigStorageCageDetails = baseMapper.selectOne(bigStorageCageDetailsWrapper);
        if (temperingGlassInfo.getState() == -2) {
            temperingGlassInfoMapper.deleteById(temperingGlassInfo);
        } else {
            temperingGlassInfo.setState(5);
        if (temperingGlassInfo != null) {
            if (status == 0) {
                temperingGlassInfo.setState(Const.TEMPERING_DAMAGE);
            } else {
                temperingGlassInfo.setState(Const.TEMPERING_TAKE);
            }
            temperingGlassInfoMapper.updateById(temperingGlassInfo);
        }
        baseMapper.deleteById(bigStorageCageDetails.getId());
        if (status == 0) {
            bigStorageCageDetails.setState(Const.GLASS_STATE_TAKE);
        } else {
            bigStorageCageDetails.setState(Const.GLASS_STATE_DAMAGE);
        }
        baseMapper.updateById(bigStorageCageDetails);
        bigStorageCageService.updateRemainWidth(bigStorageCageDetails.getSlot());
        //todo:插入破损数据
@@ -156,20 +179,25 @@
    //查询玻璃信息
    @Override
    public BigStorageCageDetails selectBigStorageCageDetails(String glassId) {
    public List<BigStorageCageDetails> selectBigStorageCageDetails(String glassId) {
        LambdaQueryWrapper<GlassInfo> glassInfoWrapper = new LambdaQueryWrapper<>();
        glassInfoWrapper.eq(GlassInfo::getGlassId, glassId);
        GlassInfo glassInfo = glassInfoMapper.selectOne(glassInfoWrapper);
        BigStorageCageDetails bigStorageCageDetails = new BigStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, bigStorageCageDetails);
        bigStorageCageDetails.setState(0);
        bigStorageCageDetails.setGap(20);
        return bigStorageCageDetails;
        if (glassInfo != null) {
            BeanUtils.copyProperties(glassInfo, bigStorageCageDetails);
            bigStorageCageDetails.setState(1);
            bigStorageCageDetails.setGap(galssGap);
        }
        List<BigStorageCageDetails> bigStorageCageDetailsList = new ArrayList<>();
        bigStorageCageDetailsList.add(bigStorageCageDetails);
        return bigStorageCageDetailsList;
    }
    //理片笼详情添加
    @Override
    public void insertBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
        bigStorageCageDetails.setState(100);
        baseMapper.insert(bigStorageCageDetails);
        bigStorageCageService.updateRemainWidth(bigStorageCageDetails.getSlot());
    }
@@ -177,62 +205,48 @@
    //理片笼详情完成
    @Override
    public void finishBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
        if (bigStorageCageDetails.getState() == 1 || bigStorageCageDetails.getState() == 2) {
            bigStorageCageDetails.setState(0);
            baseMapper.updateById(bigStorageCageDetails);
            bigStorageCageFeedTaskMapper.deleteById(bigStorageCageDetails.getBigStorageCageFeedTask().getId());
        } else {
            baseMapper.deleteById(bigStorageCageDetails.getId());
            bigStorageCageOutTaskMapper.deleteById(bigStorageCageDetails.getBigStorageCageOutTask().getId());
        }
//        if (bigStorageCageDetails.getBigStorageCageFeedTask() != null) {
//            bigStorageCageDetails.setState(Const.BIG_STORAGE_INSIDE);
//            baseMapper.updateById(bigStorageCageDetails);
//        } else {
//            bigStorageCageDetails.setState(Const.BIG_STORAGE_OUTSIDE);
//            baseMapper.updateById(bigStorageCageDetails);
//            bigStorageCageService.updateRemainWidth(bigStorageCageDetails.getSlot());
//        }
    }
    //手动出片
    @Override
    public void outBigStorageCageDetails(BigStorageCageDetails bigStorageCageDetails) {
        LambdaQueryWrapper<TemperingGlassInfo> temperingGlassInfoWrapper = new LambdaQueryWrapper<>();
        temperingGlassInfoWrapper
                .eq(TemperingGlassInfo::getGlassId, bigStorageCageDetails.getGlassId());
        TemperingGlassInfo temperingGlassInfo = temperingGlassInfoMapper.selectOne(temperingGlassInfoWrapper);
        if (temperingGlassInfo.getGlassId() == null) {
            LambdaQueryWrapper<GlassInfo> glassInfoWrapper = new LambdaQueryWrapper<>();
            glassInfoWrapper
                    .eq(GlassInfo::getGlassId, bigStorageCageDetails.getGlassId());
            GlassInfo glassInfo = glassInfoMapper.selectOne(glassInfoWrapper);
            TemperingGlassInfo temperingGlassInfo1 = new TemperingGlassInfo();
            BeanUtils.copyProperties(glassInfo, temperingGlassInfo1);
            if (temperingGlassInfo.getTemperingLayoutId() != null) {
                temperingGlassInfo1.setState(-1);
            } else {
                temperingGlassInfo1.setState(-2);
            }
            temperingGlassInfoMapper.insert(temperingGlassInfo1);
        }
        bigStorageCageDetails.setState(Const.GLASS_STATE_ARTIFICIAL);
        baseMapper.updateById(bigStorageCageDetails);
    }
    @Override
    public BigStorageDTO queryTargetSlotByTempering(GlassInfo glassInfo) {
//        MPJLambdaWrapper<BigStorageDTO> wrapper = new MPJLambdaWrapper<>(BigStorageCage.class)
//                .selectAll(BigStorageDTO.class)
//                .leftJoin(BigStorageCageDetails.class, BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
//                .eq(BigStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
//                .eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() + 1)
//                .last("limit 1");
        BigStorageDTO bigStorageDTO = null;
        MPJLambdaWrapper<BigStorageCage> wrapper = new MPJLambdaWrapper<>(BigStorageCage.class)
                .selectAsClass(BigStorageCage.class, BigStorageDTO.class)
                .selectAll(BigStorageCage.class)
                .leftJoin(BigStorageCageDetails.class, BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .eq(BigStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
                .eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() + 1)
                .gt(BigStorageCage::getRemainWidth, glassInfo.getWidth())
                .last("limit 1");
        bigStorageDTO = bigStorageCageService.selectJoinOne(BigStorageDTO.class, wrapper);
        if (null != bigStorageDTO) {
        if (glassInfo.getTemperingLayoutId() == 0) {
            wrapper.eq(BigStorageCageDetails::getWidth, glassInfo.getWidth()).eq(BigStorageCageDetails::getHeight, glassInfo.getHeight());
        } else {
            wrapper.eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() + 1);
        }
        BigStorageCage bigStorageCage = bigStorageCageService.selectJoinOne(BigStorageCage.class, wrapper);
        if (null != bigStorageCage) {
            bigStorageDTO = new BigStorageDTO();
            bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
            bigStorageDTO.setSlot(bigStorageCage.getSlot());
            return bigStorageDTO;
        }
        BigStorageCage bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getRemainWidth, Const.BIG_STORAGE_WIDTH)
        bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .eq(BigStorageCage::getRemainWidth, slotWidth)
                .inSql(BigStorageCage::getDeviceId,
                        "select distinct device_id from big_storage_cage_details where tempering_layout_id = " + glassInfo.getTemperingLayoutId())
                .last("limit 1"));
@@ -243,14 +257,29 @@
            return bigStorageDTO;
        }
        bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getRemainWidth, Const.BIG_STORAGE_WIDTH)
                .eq(BigStorageCage::getRemainWidth, slotWidth)
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .last("limit 1"));
        Assert.isTrue(null != bigStorageCage, "没有空余的笼子存放玻璃");
        bigStorageDTO = new BigStorageDTO();
        bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
        bigStorageDTO.setSlot(bigStorageCage.getSlot());
        return bigStorageDTO;
    }
    @Override
    public TemperingLayoutDTO temperingIsAll() {
        return baseMapper.temperingIsAll();
    }
    @Override
    public TemperingLayoutDTO queryTemperingOccupySlot() {
        return baseMapper.queryTemperingOccupySlot(minCount);
    }
    @Override
    public List<SlotSequenceDTO> queryGlassMaxAndMin(String engineerId, Integer temperingLayoutId) {
        return baseMapper.queryGlassMaxAndMin(engineerId, temperingLayoutId);
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageServiceImpl.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.bigstorage.entity.BigStorageCage;
@@ -12,18 +11,16 @@
import com.mes.bigstorage.mapper.BigStorageCageDetailsMapper;
import com.mes.bigstorage.mapper.BigStorageCageMapper;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.common.config.Const;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import lombok.extern.slf4j.Slf4j;
import com.mes.glassinfo.entity.GlassInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -57,9 +54,9 @@
    public BigStorageCageDetails feedGlass(GlassInfo glassInfo, BigStorageCageDetails bigStorageCageDetails) {
        BeanUtils.copyProperties(glassInfo, bigStorageCageDetails);
        //玻璃不钢化时
        if(glassInfo.getTemperingLayoutId()==null){
        if (glassInfo.getTemperingLayoutId() == null) {
            BigStorageCage bigStorageCage=baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
            BigStorageCage bigStorageCage = baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
                    .selectAll(BigStorageCage.class)
                    .leftJoin(BigStorageCageDetails.class, on -> on
                            .eq(BigStorageCage::getDeviceId, BigStorageCageDetails::getDeviceId)
@@ -70,15 +67,15 @@
                    .last("limit 1")
            );
            if(bigStorageCage.getSlot()!=null){
            if (bigStorageCage.getSlot() != null) {
                bigStorageCageDetails.setSlot(bigStorageCage.getSlot());
                bigStorageCageDetails.setDeviceId(bigStorageCage.getDeviceId());
            }
        }else{
        } else {
            //玻璃钢化时
            BigStorageCage bigStorageCage=new BigStorageCage();
            BigStorageCage bigStorageCage = new BigStorageCage();
            bigStorageCage=baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
            bigStorageCage = baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
                    .selectAll(BigStorageCage.class)
                    .leftJoin(BigStorageCageDetails.class, on -> on
                            .eq(BigStorageCage::getDeviceId, BigStorageCageDetails::getDeviceId)
@@ -87,16 +84,16 @@
                    .eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() - 1)
                    .gt(BigStorageCage::getRemainWidth, glassInfo.getWidth())
            );
            log.info("1、查询理片笼内片序-1等于当前玻璃片序的玻璃"+bigStorageCage);
            log.info("1、查询理片笼内片序-1等于当前玻璃片序的玻璃" + bigStorageCage);
            log.info("2、查询理片笼内片序-1等于当前玻璃片序的玻璃的结果不为空时"+bigStorageCage.getSlot());
            log.info("2、查询理片笼内片序-1等于当前玻璃片序的玻璃的结果不为空时" + bigStorageCage.getSlot());
            if (bigStorageCage.getSlot() != null) {
                bigStorageCageDetails.setSlot(bigStorageCage.getSlot());
                bigStorageCageDetails.setDeviceId(bigStorageCage.getDeviceId());
            } else {
                log.info("3、查询理片笼内片序-1等于当前玻璃片序的玻璃的结果为空时获取当前玻璃版图id是否存在理片笼内");
                bigStorageCage=baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
                bigStorageCage = baseMapper.selectJoinOne(BigStorageCage.class, new MPJLambdaWrapper<BigStorageCage>()
                        .selectAll(BigStorageCage.class)
                        .leftJoin(BigStorageCageDetails.class, on -> on
                                .eq(BigStorageCage::getDeviceId, BigStorageCageDetails::getDeviceId)
@@ -105,12 +102,12 @@
                        .gt(BigStorageCage::getRemainWidth, glassInfo.getWidth())
                );
                if(bigStorageCage != null){
                if (bigStorageCage != null) {
                    log.info("4、获取笼子内适合的格子");
                    BigStorageCage bigStorageCages=bigStorageCageSlot(bigStorageCage.getDeviceId());
                    BigStorageCage bigStorageCages = bigStorageCageSlot(bigStorageCage.getDeviceId());
                    bigStorageCageDetails.setSlot(bigStorageCages.getSlot());
                    bigStorageCageDetails.setDeviceId(bigStorageCages.getDeviceId());
                }else{
                } else {
                    log.info("5、获取每个笼子版图id的个数");
                    QueryWrapper<BigStorageCageDetails> queryWrapper = new QueryWrapper<>();
                    queryWrapper.select("a.device_id", "COUNT(DISTINCT b.tempering_layout_id) AS layoutCount")
@@ -118,22 +115,22 @@
                            .apply("LEFT JOIN (SELECT device_id, tempering_layout_id FROM big_storage_cage_details) b ON a.device_id = b.device_id AND a.slot = b.slot")
                            .orderByAsc("layoutCount")
                            .orderByAsc("a.device_id");
                    List<Map<String, Object>> bigStorageCageDetailsCount= bigStorageCageDetailsMapper.selectMaps(queryWrapper);
                    List<Map<String, Object>> bigStorageCageDetailsCount = bigStorageCageDetailsMapper.selectMaps(queryWrapper);
                    log.info("5、查询笼子内是否有合适的格子");
                    boolean found=false;
                    boolean found = false;
                    for (Map<String, Object> map : bigStorageCageDetailsCount) {
                        for (Map.Entry<String, Object> entry : map.entrySet()) {
                            int deviceId = Integer.parseInt(entry.getKey());
                            BigStorageCage bigStorageCages=bigStorageCageSlot(deviceId);
                            if(bigStorageCage!=null){
                            BigStorageCage bigStorageCages = bigStorageCageSlot(deviceId);
                            if (bigStorageCage != null) {
                                bigStorageCageDetails.setSlot(bigStorageCages.getSlot());
                                bigStorageCageDetails.setDeviceId(deviceId);
                                found=true;
                                found = true;
                                break;
                            }
                        }
                        if(found){
                        if (found) {
                            break;
                        }
                    }
@@ -142,40 +139,39 @@
        }
        if (bigStorageCageDetails.getSlot() != null) {
            log.info("6、当找到合适的格子时添加玻璃到笼子表");
            bigStorageCageDetails.setState(0);
            bigStorageCageDetailsMapper.insert(bigStorageCageDetails);
            updateRemainWidth(bigStorageCageDetails.getSlot()) ;
            updateRemainWidth(bigStorageCageDetails.getSlot());
        }
        return bigStorageCageDetails;
    }
    //获取笼子内的空格子
    private BigStorageCage bigStorageCageSlot(Integer deviceId) {
        LambdaQueryWrapper<BigStorageCage> bigStorageCageWrapper=new LambdaQueryWrapper<>();
                bigStorageCageWrapper
                        .eq(BigStorageCage::getRemainWidth,"5000")
                        .eq(BigStorageCage::getEnableState,"0")
                        .eq(BigStorageCage::getDeviceId,deviceId)
                        .orderByAsc(BigStorageCage::getSlot)
                        .last("LIMIT 1");
                return bigStorageCageMapper.selectOne(bigStorageCageWrapper);
        LambdaQueryWrapper<BigStorageCage> bigStorageCageWrapper = new LambdaQueryWrapper<>();
        bigStorageCageWrapper
                .eq(BigStorageCage::getRemainWidth, "5000")
                .eq(BigStorageCage::getEnableState, "0")
                .eq(BigStorageCage::getDeviceId, deviceId)
                .orderByAsc(BigStorageCage::getSlot)
                .last("LIMIT 1");
        return bigStorageCageMapper.selectOne(bigStorageCageWrapper);
    }
    //出片逻辑
    @Override
    public boolean outGlass() {
        LambdaQueryWrapper<TemperingGlassInfo> temperingGlassInfoWrapper=new LambdaQueryWrapper<>();
        temperingGlassInfoWrapper.eq(TemperingGlassInfo::getState,-1);
        LambdaQueryWrapper<TemperingGlassInfo> temperingGlassInfoWrapper = new LambdaQueryWrapper<>();
        temperingGlassInfoWrapper.eq(TemperingGlassInfo::getState, -1);
        List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.list(temperingGlassInfoWrapper);
        log.info("1、查询钢化小片任务表是否有待出玻璃"+temperingGlassInfoList.size());
        if(temperingGlassInfoList.size()>0){
        log.info("1、查询钢化小片任务表是否有待出玻璃" + temperingGlassInfoList.size());
        if (temperingGlassInfoList.size() > 0) {
            temperingGlassInfoService.addOutTask(temperingGlassInfoList);
            log.info("2、添加任务到任务表");
            return true;
        }else{
        } else {
            log.info("3、没有可出的玻璃时获取是否有小片到齐的版图");
            QueryWrapper<BigStorageCageDetails> wrapper = Wrappers.query();
@@ -183,28 +179,28 @@
                    .groupBy("tempering_layout_id");
            List<Map<String, Object>> temperingLayoutIdList = bigStorageCageDetailsMapper.selectMaps(wrapper);
            boolean key=false;
            boolean key = false;
            for (Map<String, Object> row : temperingLayoutIdList) {
                for (Map.Entry<String, Object> entry : row.entrySet()) {
                    String temperingId = entry.getKey();
                    Object temperingNo = entry.getValue();
                        LambdaQueryWrapper<GlassInfo> glassInfoWrapper=new LambdaQueryWrapper<>();
                        glassInfoWrapper.eq(GlassInfo::getTemperingLayoutId,temperingId)
                                .orderByDesc(GlassInfo::getTemperingFeedSequence);
                        List<GlassInfo> glassInfoList= glassInfoService.list(glassInfoWrapper);
                        if(glassInfoList.size()==Integer.parseInt(temperingNo.toString())){
                            for (GlassInfo glassInfo:glassInfoList
                            ) {
                    LambdaQueryWrapper<GlassInfo> glassInfoWrapper = new LambdaQueryWrapper<>();
                    glassInfoWrapper.eq(GlassInfo::getTemperingLayoutId, temperingId)
                            .orderByDesc(GlassInfo::getTemperingFeedSequence);
                    List<GlassInfo> glassInfoList = glassInfoService.list(glassInfoWrapper);
                    if (glassInfoList.size() == Integer.parseInt(temperingNo.toString())) {
                        for (GlassInfo glassInfo : glassInfoList
                        ) {
                                TemperingGlassInfo temperingGlassInfo=new TemperingGlassInfo();
                                BeanUtils.copyProperties(glassInfo, temperingGlassInfo);
                                temperingGlassInfoService.save(temperingGlassInfo);
                            TemperingGlassInfo temperingGlassInfo = new TemperingGlassInfo();
                            BeanUtils.copyProperties(glassInfo, temperingGlassInfo);
                            temperingGlassInfoService.save(temperingGlassInfo);
                            }
                            key=true;
                        }
                    if(key){
                        key = true;
                    }
                    if (key) {
                        return false;
                    }
                }
@@ -217,28 +213,40 @@
    @Override
    public void updateRemainWidth(int slot) {
        log.info("获取该格子内玻璃信息,计算格子剩余宽度");
        Integer width = 5000;
        List<BigStorageCageDetails> bigStorageCageDetailsList = Collections.singletonList(bigStorageCageDetailsMapper.selectById(slot));
        double width = 5000;
        LambdaQueryWrapper<BigStorageCageDetails> bigStorageCageDetailsWrapper = new LambdaQueryWrapper();
        bigStorageCageDetailsWrapper
                .eq(BigStorageCageDetails::getSlot, slot)
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL);
        List<BigStorageCageDetails> bigStorageCageDetailsList = bigStorageCageDetailsMapper.selectList(bigStorageCageDetailsWrapper);
        for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList
        ) {
            width -= Integer.parseInt(bigStorageCageDetails.getWidth().toString()) + bigStorageCageDetails.getGap();
            double widths = bigStorageCageDetails.getWidth();
            double gap = bigStorageCageDetails.getGap();
            width -= widths + gap;
        }
        //修改格子剩余宽度
        BigStorageCage bigStorageCage = new BigStorageCage();
        bigStorageCage.setRemainWidth(width);
        bigStorageCage.setRemainWidth((int) width);
        UpdateWrapper<BigStorageCage> bigStorageCageWrapper = new UpdateWrapper<>();
        bigStorageCageWrapper.eq("remain_width", width);
        bigStorageCageWrapper.eq("slot", slot);
        bigStorageCageMapper.update(bigStorageCage, bigStorageCageWrapper);
    }
    //查询大理片信息,前端展示用
    @Override
    public List<BigStorageCage> querybigStorageCageDetail(int deviceId) {
        LambdaQueryWrapper<BigStorageCage> bigStorageCageWrapper =new LambdaQueryWrapper<>();
        LambdaQueryWrapper<BigStorageCageDetails> bigStorageCageDetailsWrapper =new LambdaQueryWrapper<>();
        if(deviceId!=0){
            bigStorageCageWrapper.eq(BigStorageCage::getDeviceId,deviceId);
            bigStorageCageDetailsWrapper.eq(BigStorageCageDetails::getDeviceId,deviceId);
        LambdaQueryWrapper<BigStorageCage> bigStorageCageWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<BigStorageCageDetails> bigStorageCageDetailsWrapper = new LambdaQueryWrapper<>();
        bigStorageCageDetailsWrapper
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                .or()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL);
        if (deviceId != 0) {
            bigStorageCageWrapper.eq(BigStorageCage::getDeviceId, deviceId);
            bigStorageCageDetailsWrapper.eq(BigStorageCageDetails::getDeviceId, deviceId);
        }
        List<BigStorageCage> bigStorageCages = bigStorageCageMapper.selectList(bigStorageCageWrapper);
@@ -254,6 +262,19 @@
        return bigStorageCages;
    }
    //查询大理片信息,前端展示用
    @Override
    public Map<Integer, List<BigStorageCage>> querybigStorageCageDetail() {
        MPJLambdaWrapper<BigStorageCage> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(BigStorageCage.class).selectCollection(BigStorageCageDetails.class, BigStorageCage::getBigStorageCageDetails)
                .leftJoin(BigStorageCageDetails.class, on -> on.eq(BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
                        .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN, Const.GLASS_STATE_ARTIFICIAL));
        List<BigStorageCage> bigStorageCages = bigStorageCageMapper.selectJoinList(BigStorageCage.class, wrapper);
        Map<Integer, List<BigStorageCage>> listMap = bigStorageCages.stream().collect(Collectors.groupingBy(item -> item.getDeviceId()));
        return listMap;
    }
    //笼子使用情况,界面展示用
    @Override
    public List<Map<String, Object>> selectBigStorageCageUsage() {
@@ -261,18 +282,18 @@
        wrapper.select("device_id,ROUND(1 - SUM(CASE WHEN remain_width = 5000 THEN 1 ELSE 0 END) / COUNT(device_id), 2) AS percentage,COUNT(device_id) - SUM(CASE WHEN remain_width = 5000 THEN 1 ELSE 0 END) AS count")
                .groupBy("device_id");
        List<Map<String, Object>> bigStorageCageUsages=baseMapper.selectMaps(wrapper);
        List<Map<String, Object>> bigStorageCageUsages = baseMapper.selectMaps(wrapper);
        return bigStorageCageUsages;
    }
    //笼子的启用/禁用
    @Override
    public void updateStorageCageDisabled(int slot,int enableState){
        BigStorageCage bigStorageCage=new BigStorageCage();
    public void updateStorageCageDisabled(int slot, int enableState) {
        BigStorageCage bigStorageCage = new BigStorageCage();
        bigStorageCage.setEnableState(enableState);
        LambdaQueryWrapper<BigStorageCage> bigStorageCageWrapper = new LambdaQueryWrapper<>();
        bigStorageCageWrapper.eq(BigStorageCage::getSlot,slot);
        baseMapper.update(bigStorageCage,bigStorageCageWrapper);
        bigStorageCageWrapper.eq(BigStorageCage::getSlot, slot);
        baseMapper.update(bigStorageCage, bigStorageCageWrapper);
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/entity/BigStorageCageFeedTask.java
@@ -42,7 +42,7 @@
     * 目标位置
     */
    @ApiModelProperty(value = "目标位置", position = 4)
    private Integer targetSlot;
    private int targetSlot;
    /**
     * 玻璃类型
@@ -60,7 +60,7 @@
     * 线路
     */
    @ApiModelProperty(value = "线路", position = 7)
    private Integer line;
    private int line;
    /**
     * 宽度
     */
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/entity/BigStorageCageOutTask.java
@@ -2,16 +2,16 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
 *
 * </p>
 *
 * @author zhoush
@@ -24,11 +24,23 @@
    private static final long serialVersionUID = 1L;
    public BigStorageCageOutTask() {
    }
    public BigStorageCageOutTask(String glassId, Integer startSlot, Integer endSlot, Integer width, Integer trainNumber, Integer serialNumber, Integer taskState) {
        this.glassId = glassId;
        this.startSlot = startSlot;
        this.endSlot = endSlot;
        this.trainNumber = trainNumber;
        this.serialNumber = serialNumber;
        this.taskState = taskState;
    }
    /**
     * 主键id
     */
      @ApiModelProperty(value = "主键id", position = 2)
      @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "主键id", position = 2)
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
@@ -66,6 +78,5 @@
     */
    @ApiModelProperty(value = "任务状态", position = 8)
    private Integer taskState;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/mapper/BigStorageCageFeedTaskMapper.java
@@ -1,8 +1,10 @@
package com.mes.bigstoragetask.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -14,8 +16,10 @@
 * @author zhoush
 * @since 2024-04-16
 */
@DS("salve_hangzhoumes")
public interface BigStorageCageFeedTaskMapper extends BaseMapper<BigStorageCageFeedTask> {
@DS("salve_hangzhoumes_1")
public interface BigStorageCageFeedTaskMapper extends MPJBaseMapper<BigStorageCageFeedTask> {
    List<String> querySitToUpGlass();
    List<Integer> querySitToUpGlass();
    BigStorageDTO querySitToUpRemainWidth(@Param(value = "line") Integer line);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/mapper/BigStorageCageOutTaskMapper.java
@@ -1,8 +1,11 @@
package com.mes.bigstoragetask.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -12,7 +15,8 @@
 * @author zhoush
 * @since 2024-04-16
 */
@DS("salve_hangzhoumes")
@DS("salve_hangzhoumes_1")
public interface BigStorageCageOutTaskMapper extends BaseMapper<BigStorageCageOutTask> {
    boolean saveBatch(@Param(value = "list") List<BigStorageCageOutTask> list);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/BigStorageCageFeedTaskService.java
@@ -1,7 +1,9 @@
package com.mes.bigstoragetask.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.base.MPJBaseService;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import java.util.List;
@@ -14,7 +16,7 @@
 * @author zhoush
 * @since 2024-04-16
 */
public interface BigStorageCageFeedTaskService extends IService<BigStorageCageFeedTask> {
public interface BigStorageCageFeedTaskService extends MPJBaseService<BigStorageCageFeedTask> {
    void addFeedTask(BigStorageCageDetails slotInfo, Integer plcFeedReqLine, int taskType);
@@ -23,5 +25,10 @@
    /**
     * 查询卧转立玻璃是否进片完成
     */
    List<String> querySitToUpGlass();
    BigStorageDTO querySitToUpRemainWidth(Integer line);
    /**
     * 查询卧转立玻璃是否进片完成
     */
    List<Integer> querySitToUpGlass();
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/BigStorageCageOutTaskService.java
@@ -1,7 +1,7 @@
package com.mes.bigstoragetask.service;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import java.util.List;
@@ -19,5 +19,7 @@
    void updateOutTask();
    boolean saveBatch(List<BigStorageCageOutTask> list);
    void deleteOutTask(String glassId);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageFeedTaskServiceImpl.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.mapper.BigStorageCageFeedTaskMapper;
import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
@@ -39,7 +40,12 @@
    }
    @Override
    public List<String> querySitToUpGlass() {
    public BigStorageDTO querySitToUpRemainWidth(Integer line) {
        return baseMapper.querySitToUpRemainWidth(line);
    }
    @Override
    public List<Integer> querySitToUpGlass() {
        return baseMapper.querySitToUpGlass();
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageOutTaskServiceImpl.java
@@ -1,13 +1,12 @@
package com.mes.bigstoragetask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.mapper.BigStorageCageDetailsMapper;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.mes.bigstoragetask.mapper.BigStorageCageOutTaskMapper;
import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.mapper.TemperingGlassInfoMapper;
import lombok.extern.slf4j.Slf4j;
@@ -35,14 +34,19 @@
    @Resource
    BigStorageCageDetailsMapper bigStorageCageDetailsMapper;
    @Override
    public boolean saveBatch(List<BigStorageCageOutTask> list) {
        return baseMapper.saveBatch(list);
    }
    /**
     * 查询任务信息
     */
    @Override
    public List<BigStorageCageOutTask> querybigStorageCageOutTask(int taskState){
        log.info("根据传入的任务状态查询任务信息:"+taskState);
        LambdaQueryWrapper<BigStorageCageOutTask> getOutTaskWrapper=new LambdaQueryWrapper<>();
        getOutTaskWrapper.eq(BigStorageCageOutTask::getTaskState,taskState);
    public List<BigStorageCageOutTask> querybigStorageCageOutTask(int taskState) {
        log.info("根据传入的任务状态查询任务信息:" + taskState);
        LambdaQueryWrapper<BigStorageCageOutTask> getOutTaskWrapper = new LambdaQueryWrapper<>();
        getOutTaskWrapper.eq(BigStorageCageOutTask::getTaskState, taskState);
        return baseMapper.selectList(getOutTaskWrapper);
    }
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/common/S7object.java
@@ -14,7 +14,7 @@
public class S7object extends Thread {
    public S7control plccontrol; // PLC通讯类实例
    private EPlcType plcType = EPlcType.S1200; // 西门子PLC类型
    private String ip = "192.168.10.1"; // plc ip地址
    private String ip = "192.168.20.2"; // plc ip地址
    private int port = 102; // plc 端口号
@@ -25,8 +25,8 @@
        if (plccontrol == null) {
            plccontrol = new S7control(plcType, ip, port, 0, 0);
            String PlcLoadGlass=S7object.class.getResource("/JsonFile/PlcCacheVerticalGlass.json").getPath();
            //log.info(PLCAutoMes.class.getResource("").getPath());
            String PlcLoadGlass = System.getProperty("user.dir") + "/JsonFile/PlcCacheVerticalGlass.json";
            System.out.println("获取到的文件路径为:" + PlcLoadGlass);
            PlcMesObject = InitUtil.initword(PlcLoadGlass);
        }
    }
@@ -54,8 +54,9 @@
            }
            byte[] getplcvlues = plccontrol.readByte(PlcMesObject.getPlcAddressBegin(), PlcMesObject.getPlcAddressLength());
            PlcMesObject.setPlcParameterList(getplcvlues);
            if (getplcvlues != null) {
                PlcMesObject.setPlcParameterList(getplcvlues);
            }
        }
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/controller/DamageController.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/entity/Damage.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/damage/service/DamageService.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/controller/TaskCacheController.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/entity/TaskCache.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/mapper/TaskCacheMapper.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/service/TaskCacheService.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/edgstoragetask/service/impl/TaskCacheServiceImpl.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/controller/GlassInfoController.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/mapper/GlassInfoMapper.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/service/GlassInfoService.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/glassinfo/service/impl/GlassInfoServiceImpl.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcSlicecage.java
@@ -36,7 +36,7 @@
     * fixedRate : 上一个调用开始后再次调用的延时(不用等待上一次调用完成)
     * fixedDelay : 上一个调用结束后再次调用的延时
     */
    @Scheduled(fixedDelay = 5000)
    @Scheduled(fixedDelay = 1000)
    public void plcStorageCageTask() throws InterruptedException {
        JSONObject jsonObject = new JSONObject();
        try {
@@ -65,9 +65,6 @@
            //出片队列
            List<TemperingGlassInfo> temperingGlassInfoList= temperingGlassInfoService.list();
            jsonObject.append("temperingGlassInfoList", temperingGlassInfoList);
            //报警信息
            jsonObject.append("bigStorageCageFullAlarm", PlcStorageCageTask.bigStorageCageFullAlarm);
            //理片笼表格信息
            jsonObject.append("bigStorageCageInfo", bigStorageCageService.querybigStorageCageDetail(0));
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcStorageCageTask.java
@@ -2,12 +2,20 @@
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
import com.mes.common.S7object;
@@ -17,22 +25,18 @@
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.tools.S7control;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -57,217 +61,237 @@
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    private static final String REQUEST_WORD = "1";
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
    public static boolean bigStorageCageFullAlarm = false;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    private int line1Time = 0;
    private int line2Time = 0;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    /**
     * fixedRate : 上一个调用开始后再次调用的延时(不用等待上一次调用完成)
     * fixedDelay : 上一个调用结束后再次调用的延时
     */
//    @Scheduled(fixedDelay = 5000)
//    public void plcStorageCageTask() throws InterruptedException {
//
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        try {
//
//            String plcFeedGlassid = "";
//            String plcFeedReqLine = "0";
//            if ("1".equals(plcParameterObject.getPlcParameter("D01Request").getValue())) {
//                plcFeedReqLine = "1";
//                plcFeedGlassid = plcParameterObject.getPlcParameter("D01ID1").getValue();
//            }
//            if ("1".equals(plcParameterObject.getPlcParameter("D04Request").getValue())) {
//                plcFeedReqLine = "2";
//                plcFeedGlassid = plcParameterObject.getPlcParameter("D04ID1").getValue();
//            }
//            line1Time += 1;
//            line2Time += 1;
//
//            if (!("0".equals(plcFeedReqLine))) {
//                log.info("1、Plc进片请求时");
//                BigStorageCageDetails bigStorageCageDetails = new BigStorageCageDetails();
//                GlassInfo glassInfo = glassInfoService.getById(plcFeedGlassid);
//                log.info("2、根据玻璃id获取玻璃信息" + glassInfo);
//                if (bigStorageCageDetailsService.selectGetBoard(plcFeedReqLine) >= 0) {
//                    BigStorageCageDetails slotInfo = bigStorageCageService.feedGlass(glassInfo, bigStorageCageDetails);
//                    if (slotInfo != null) {
//                        int taskType = edgGlassTaskInfoService.judgeTasktype(plcFeedReqLine);
//                        log.info("3、查询任务表判断当前任务类型为上车等到还是上车启动" + taskType);
//                        bigStorageCageFeedTaskService.addFeedTask(slotInfo, Integer.parseInt(plcFeedReqLine), taskType);
//                        log.info("4、添加任务到任务表");
//                        bigStorageCageFullAlarm = false;
//                    } else {
//                        bigStorageCageFullAlarm = true;
//                    }
//                } else {
//                    log.info("当前玻璃宽度不够上车" + glassInfo);
//                    if (!("1".equals(plcFeedReqLine))) {
//                        S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D02Go").getAddress(), 1);
//                    } else {
//                        S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D05Go").getAddress(), 1);
//                    }
//                }
//            } else {
//                List<BigStorageCageFeedTask> bigStorageCageFeedTaskList = bigStorageCageFeedTaskService.querybigStorageCageFeedTask(1);
//                log.info("5、查询任务表是否有已经完成的进片任务" + bigStorageCageFeedTaskList.size());
//                for (BigStorageCageFeedTask bigStorageCageFeedTask : bigStorageCageFeedTaskList
//                ) {
//                    BigStorageCageDetails bigStorageCageDetails = new BigStorageCageDetails();
//                    bigStorageCageDetails.setId(bigStorageCageFeedTask.getId());
//                    bigStorageCageDetails.setState(1);
//                    bigStorageCageDetailsService.updateById(bigStorageCageDetails);
//                    log.info("6、修改理片笼详情玻璃状态");
//                    bigStorageCageFeedTaskService.removeById(bigStorageCageFeedTask);
//                    log.info("7、删除已经完成的进片任务");
//                }
//                //启动阈值
//                if (line1Time >= 300) {
//                    if ("0".equals(plcParameterObject.getPlcParameter("D05Go").getValue())) {
//                        S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D02Go").getAddress(), 1);
//                    }
//                }
//                if (line2Time >= 300) {
//                    if ("0".equals(plcParameterObject.getPlcParameter("D02Go").getValue())) {
//                        S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D05Go").getAddress(), 1);
//                    }
//                }
//            }
//
//            //查询出片表是否有任务未完成的任务
//            List<BigStorageCageOutTask> bigStorageCageOutTask = bigStorageCageOutTaskService.querybigStorageCageOutTask(0);
//            if (bigStorageCageOutTask.size() == 0) {
//                boolean result = bigStorageCageService.outGlass();
//                log.info("8、没有未完成任务时调用出片接口");
//                if (result == false) {
//                    temperingGlassInfoService.schedulingTask();
//                }
//            }
//            bigStorageCageOutTaskService.updateOutTask();
//            log.info("9、根据任务表状态修改钢化小片表任务状态");
//
//            //来不及送时直接走
//            String line = Integer.toString(edgGlassTaskInfoService.startTask());
//
//            if (!(line.equals(plcFeedReqLine))) {
//                S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D02Go").getAddress(), 1);
//            } else {
//                S7object.getinstance().plccontrol.writetime(plcParameterObject.getPlcParameter("D05Go").getAddress(), 1);
//            }
//
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    @Scheduled(fixedDelay = 5000)
    @Value("${mes.inCarMaxSize}")
    private Integer inCarMaxSize;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.galssGap}")
    private Integer galssGap;
    @Scheduled(fixedDelay = 300)
    public void plcToHomeEdgScan() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String d01Request = plcParameterObject.getPlcParameter("D01Request").getValue();
        String d01ID1 = plcParameterObject.getPlcParameter("D01ID1").getValue();
        String d04Request = plcParameterObject.getPlcParameter("D04Request").getValue();
        String d04ID1 = plcParameterObject.getPlcParameter("D04ID1").getValue();
        log.info("1、获取到的请求字d01为:{},获取到的扫描ID为:{};获取到的请求字d04为:{},获取到的扫描ID为:{};",
                d01Request, d01ID1, d04Request, d04ID1);
        if (!"1".equals(d01Request) && !"1".equals(d04Request)) {
        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
        //D02id判断是否为空  确认是否空闲 允许进片
        String d02State = plcParameterObject.getPlcParameter("D02ID").getValue();
        String d03State = plcParameterObject.getPlcParameter("D03State").getValue();
        String d05State = plcParameterObject.getPlcParameter("D05State").getValue();
        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
        if (!REQUEST_WORD.equals(d01ToMES)) {
            log.info("请求字为{},结束本次扫描进卧转立任务", d01ToMES);
            return;
        }
        log.info("1、获取d01Id扫描ID为:{};获取d04Id扫描ID为:{};", d01Id, d04Id);
        if (StringUtils.isBlank(d01Id) && StringUtils.isBlank(d04Id)) {
            log.info("两条线未收到进片任务,结束本次扫描进卧转立任务");
            return;
        }
        //        0:不干预 ; 1:条件满足情况下立即发车
        String d02GoAdress = plcParameterObject.getPlcParameter("D02Go").getAddress();
        //        0:不干预 ; 1:条件满足情况下立即发车
        String d05GoAdress = plcParameterObject.getPlcParameter("D05Go").getAddress();
        Boolean flag01 = Boolean.FALSE;
        Boolean flag04 = Boolean.FALSE;
        if (REQUEST_WORD.equals(d03State) && REQUEST_WORD.equals(d05State)) {
            log.info("两条线卧转立均在执行任务,结束本次扫描进卧转立任务");
            return;
        }
//        Boolean flag01 = Boolean.FALSE;
//        Boolean flag04 = Boolean.FALSE;
        //按照线路及玻璃id获取相邻两块玻璃 卧转立上的玻璃
        if ("1".equals(d01Request)) {
            flag01 = judgeGlassTypeStatus(d01ID1, Const.A09_OUT_TARGET_POSITION);
        if (StringUtils.isNotBlank(d01Id) && (StringUtils.isBlank(d02State) || !REQUEST_WORD.equals(d03State))) {
            judgeGlassTypeStatus(d01Id, Const.A09_OUT_TARGET_POSITION, mesD01Address);
        }
        if ("1".equals(d04Request)) {
            flag04 = judgeGlassTypeStatus(d04ID1, Const.A10_OUT_TARGET_POSITION);
        if (StringUtils.isNotBlank(d04Id) && !REQUEST_WORD.equals(d05State)) {
            judgeGlassTypeStatus(d04Id, Const.A10_OUT_TARGET_POSITION, mesD04Address);
        }
        if (flag01 && flag04) {
            //比较最早一片任务的版图id及版序 求出卧转立的线路
            Integer startLine = getStartLine();
            //计算目标格子,发送启动任务
            computeTargetByLine(startLine, d02GoAdress, d05GoAdress);
        } else if (flag01 || flag04) {
            Integer startLine = flag01.equals(Boolean.TRUE) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
            //计算目标格子,发送启动任务
            computeTargetByLine(startLine, d02GoAdress, d05GoAdress);
        } else {
            log.info("两条线未收到进片任务,结束本次扫描进卧转立任务");
        }
        log.info("结束扫码任务");
//        if (flag01 && flag04) {
//            //比较最早一片任务的版图id及版序 求出卧转立的线路
//            Integer startLine = getStartLine();
//            //计算目标格子,发送启动任务
//            computeTargetByLine(startLine);
//        } else if (flag01 || flag04) {
//            Integer startLine = flag01.equals(Boolean.TRUE) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//            //计算目标格子,发送启动任务
//            computeTargetByLine(startLine);
//        } else {
//            log.info("两条线未收到进片任务,结束本次扫描进卧转立任务");
//        }
    }
    @Scheduled(fixedDelay = 5000)
    @Scheduled(fixedDelay = 300)
    public void plcToHomeEdgFreeCarTask() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String freeCar = plcParameterObject.getPlcParameter("freeCar").getValue();
        if ("1".equals(freeCar)) {
            log.info("大车非空闲");
        String e01Status = plcParameterObject.getPlcParameter("E01State").getValue();
        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
        log.info("执行空车送片任务,获取到的大车状态为{},卧转立状态分别为d03:{},d05:{}", e01Status, d03ToMES, d05ToMES);
        if (REQUEST_WORD.equals(e01Status)) {
            log.info("进片大车非空闲,结束送片任务");
            return;
        }
        String d01Request = plcParameterObject.getPlcParameter("D01Request").getValue();
        String d01ID1 = plcParameterObject.getPlcParameter("D01ID1").getValue();
        String d04Request = plcParameterObject.getPlcParameter("D04Request").getValue();
        String d04ID1 = plcParameterObject.getPlcParameter("D04ID1").getValue();
        log.info("1、获取到的请求字d01为:{},获取到的扫描ID为:{};获取到的请求字d04为:{},获取到的扫描ID为:{};",
                d01Request, d01ID1, d04Request, d04ID1);
        if (!REQUEST_WORD.equals(d03ToMES) && !REQUEST_WORD.equals(d05ToMES)) {
            log.info("卧转立没有送片请求,结束送片任务");
            return;
        }
        LambdaQueryWrapper<BigStorageCageFeedTask> wrapper = new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .eq(BigStorageCageFeedTask::getTaskType, Const.BIG_STORAGE_IN_RUN)
                .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP);
        //获取可以启动卧转立的任务线路
        List<BigStorageCageFeedTask> feedTaskList = bigStorageCageFeedTaskService.list(wrapper);
        if (CollectionUtils.isNotEmpty(feedTaskList)) {
            if (feedTaskList.size() == 1) {
                computeTargetByLine(feedTaskList.get(0).getLine());
                return;
            } else {
                //比较最早一片任务的版图id及版序 求出卧转立的线路
                Integer startLine = getStartLine();
//            //计算目标格子,发送启动任务
                computeTargetByLine(startLine);
                return;
            }
        }
        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
        log.info("1、获取d01Id扫描ID为:{};获取d04Id扫描ID为:{};", d01Id, d04Id);
        //两条线都有进卧转立任务,直接结束
        if (Const.BIG_STORAGE_REQUEST_IN.equals(d01Request)
                && Const.BIG_STORAGE_REQUEST_IN.equals(d04Request)
                && StringUtils.isNotBlank(d01ID1)
                && StringUtils.isNotBlank(d04ID1)) {
            log.info("两条线都存在进片任务,结束任务");
            return;
        }
//        if (StringUtils.isNotBlank(d01Id) && StringUtils.isNotBlank(d04Id)) {
//            log.info("两条线都存在进片任务,结束任务");
//            return;
//        }
        //获取两条线卧转立是否有玻璃,且任务状态都为2
        List<String> lineList = bigStorageCageFeedTaskService.querySitToUpGlass();
        List<Integer> lineList = bigStorageCageFeedTaskService.querySitToUpGlass();
        if (CollectionUtils.isEmpty(lineList)) {
            log.info("两条线卧转立为空或者有进片任务未完成,结束任务");
            return;
        }
//        0:不干预 ; 1:条件满足情况下立即发车
        String d02GoAdress = plcParameterObject.getPlcParameter("D02Go").getAddress();
        //        0:不干预 ; 1:条件满足情况下立即发车
        String d05GoAdress = plcParameterObject.getPlcParameter("D05Go").getAddress();
        String line1 = lineList.get(0);
        String flagLine = line1.equals(Const.A09_OUT_TARGET_POSITION) ? d01ID1 : d04ID1;
        Integer lineFirst = lineList.get(0);
        String lineGlassId = lineFirst.equals(Const.A09_OUT_TARGET_POSITION) ? d01Id : d04Id;
        //仅有一条先符合启动启动条件
        if (lineList.size() == 1) {
            //发送
            if (StringUtils.isNotBlank(flagLine)) {
                return;
            //如果进片请求但玻璃为空,计算任务表进片格子 发送进片任务
            if (StringUtils.isEmpty(lineGlassId)) {
                computeTargetByLine(lineFirst);
            } else {
                //todo:计算扫描到的玻璃是否可以存进卧转立
                //获取卧转立剩余宽度
                if (computeIsRun(lineFirst, lineGlassId)) {
                    computeTargetByLine(lineFirst);
                }
            }
            //计算任务表进片格子 发送进片任务
            computeTargetByLine(Integer.parseInt(flagLine), d02GoAdress, d05GoAdress);
            return;
        }
        if (StringUtils.isBlank(d01ID1) && StringUtils.isBlank(d04ID1)) {
        //两条先均可执行进片任务,判断两条线是否进片请求是否都为空
        if (StringUtils.isBlank(d01Id) && StringUtils.isBlank(d04Id)) {
            //比较最早一片任务的版图id及版序 求出卧转立的线路
            Integer line = getStartLine();
            //计算任务表进片格子 发送进片任务
            computeTargetByLine(line, d02GoAdress, d05GoAdress);
            computeTargetByLine(line);
            return;
        } else if (StringUtils.isNotBlank(d01Id) && StringUtils.isNotBlank(d04Id)) {
//            todo:两个都有进片玻璃
            if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id) && computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
                //比较最早一片任务的版图id及版序 求出卧转立的线路
                Integer line = getStartLine();
                //计算任务表进片格子 发送进片任务
                computeTargetByLine(line);
            } else if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id)) {
                computeTargetByLine(Const.A09_OUT_TARGET_POSITION);
            } else if (computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
                computeTargetByLine(Const.A10_OUT_TARGET_POSITION);
            } else {
                return;
            }
        } else {
            //,或者仅有一条有玻璃
            //一条线为空,一条线有进片请求有玻璃
            int outLine = StringUtils.isBlank(d01Id) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
            //获取进片请求玻璃为空的,计算任务表进片格子 发送进片任务
            computeTargetByLine(outLine);
        }
        int outLine = StringUtils.isBlank(d01ID1) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
        //计算任务表进片格子 发送进片任务
        computeTargetByLine(outLine, d02GoAdress, d05GoAdress);
    }
    @Scheduled(fixedDelay = 5000)
    @Scheduled(fixedDelay = 300)
    public void plcToHomeEdgOutTask() {
        List<BigStorageCageOutTask> outingList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>().eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_NEW));
        Assert.isTrue(CollectionUtils.isEmpty(outingList), "有正在执行出片的任务,结束当前出片线程");
        //是否有正在钢化的玻璃
        List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.selectJoinList(TemperingGlassInfo.class, new MPJLambdaWrapper<TemperingGlassInfo>()
                .selectAll(TemperingGlassInfo.class)
                .leftJoin(BigStorageCageOutTask.class, BigStorageCageOutTask::getGlassId, TemperingGlassInfo::getGlassId)
                .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW)
                .isNull(BigStorageCageOutTask::getGlassId)
                .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlassInfo::getTemperingFeedSequence));
        if (CollectionUtils.isNotEmpty(temperingGlassInfoList)) {
            log.info("有正在出片的钢化任务");
            computeOutGlassInfo(temperingGlassInfoList, Boolean.TRUE);
            return;
        }
        //是否有人工下片任务   有直接出
        List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL).orderByDesc(BigStorageCageDetails::getWidth));
        if (CollectionUtils.isNotEmpty(artificialList)) {
            computeOutGlassInfo(temperingGlassInfoList, Boolean.FALSE);
            return;
        }
        //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
        TemperingLayoutDTO temperingLayoutDTO = bigStorageCageDetailsService.temperingIsAll();
        if (null != temperingLayoutDTO) {
            //玻璃到齐
            //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
            List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
                    .selectAll(GlassInfo.class)
                    .select("-1 as state")
                    .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
                    .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .eq(GlassInfo::getTemperingLayoutId, temperingLayoutDTO.getTemperingLayoutId())
                    .eq(GlassInfo::getEngineerId, temperingLayoutDTO.getEngineerId()));
            temperingGlassInfoService.saveBatch(temperingGlassInfos);
            computeOutGlassInfo(temperingGlassInfoList, Boolean.TRUE);
            return;
        }
        //未到齐 执行内部调度任务
        TemperingLayoutDTO temperingOccupySlot = bigStorageCageDetailsService.queryTemperingOccupySlot();
        if (null != temperingOccupySlot) {
            List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
            for (int i = 0; i < slotSequenceList.size() - 1; i++) {
                SlotSequenceDTO first = slotSequenceList.get(i);
                SlotSequenceDTO second = slotSequenceList.get(i + 1);
                int slotWidth = carWidth - first.getRemainWidth() - galssGap;
                if (first.getMinSequence() == second.getMaxSequence() + 1
                        && second.getRemainWidth() > slotWidth) {
                    List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                            .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN));
                    List<BigStorageCageOutTask> outTasks = list.stream().map(e -> new BigStorageCageOutTask(e.getGlassId(), first.getSlot(), second.getSlot(),
                            slotWidth, 0, 0, 1)).collect(Collectors.toList());
                    bigStorageCageOutTaskService.saveBatch(outTasks);
                    return;
                }
            }
        }
    }
    /**
     * 按照玻璃id判断玻璃状态及卧转立是否可直接启动
     */
    public Boolean judgeGlassTypeStatus(String glassId, Integer line) {
    public Boolean judgeGlassTypeStatus(String glassId, Integer line, String mesAddress) {
        //1、获取任务表中相邻玻璃
        List<EdgGlassTaskInfo> edgGlassTaskInfoList = edgGlassTaskInfoService.list(new LambdaQueryWrapper<EdgGlassTaskInfo>()
                .eq(EdgGlassTaskInfo::getLine, line)
@@ -275,33 +299,52 @@
                .orderByAsc(EdgGlassTaskInfo::getTime));
        Assert.isFalse(CollectionUtils.isEmpty(edgGlassTaskInfoList), "识别玻璃信息未出现在尺寸表中,获取相邻两块玻璃失败");
        //2、获取卧转立剩余宽度
        Map<String, Object> map = bigStorageCageFeedTaskService.getMap(new QueryWrapper<BigStorageCageFeedTask>()
                .select("cast(5000 - sum(width + 20)  as INT)as remainWidth")
                .eq("line", line).eq("task_state", Const.BIG_STORAGE_IN_UP));
        Integer remainWidth = null == map ? 5000 : Integer.parseInt(map.get("remainWidth") + "");
        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
        Integer remainWidth;
        Integer glassCount;
        if (0 == sitToUpRemainWidth.getGlassCount()) {
            remainWidth = carWidth;
            glassCount = 0;
        } else {
            remainWidth = sitToUpRemainWidth.getWidth();
            glassCount = sitToUpRemainWidth.getGlassCount();
        }
        Boolean flag = Boolean.TRUE;
        //2、获取卧转立
        Integer widthFirst = edgGlassTaskInfoList.get(0).getWidth();
        if (edgGlassTaskInfoList.size() == 1) {
            if (remainWidth >= widthFirst) {
                addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst);
                return Boolean.FALSE;
                if (glassCount <= 5) {
                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst);
                } else {
                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst);
                }
            } else {
                //记录无法放下玻璃,后续判断启动
                return Boolean.TRUE;
                flag = Boolean.FALSE;
            }
        }
        Integer widthSecond = edgGlassTaskInfoList.get(1).getWidth();
        if (remainWidth >= widthFirst) {
            if (remainWidth - widthFirst - Const.BIG_STORAGE_GAP >= widthSecond) {
                addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthSecond);
            } else {
                addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthSecond);
            }
            return Boolean.FALSE;
        } else {
            return Boolean.TRUE;
            Integer widthSecond = edgGlassTaskInfoList.get(1).getWidth();
            if (remainWidth >= widthFirst) {
                if (remainWidth - widthFirst - galssGap >= widthSecond) {
                    if (glassCount <= inCarMaxSize - 1) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst);
                    } else {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst);
                    }
                } else {
                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst);
                }
            } else {
                flag = Boolean.FALSE;
            }
        }
        //向plc发送进片确认
        if (flag) {
            S7object.getinstance().plccontrol.writeWord(mesAddress, 1);
        }
        //记录无法放下玻璃,后续判断启动
        return flag;
    }
    /**
@@ -310,7 +353,7 @@
    private Boolean addFeedTask(String glassId, Integer line, Integer taskType, Integer width) {
        BigStorageCageFeedTask bigStorageCageFeedTask = new BigStorageCageFeedTask();
        bigStorageCageFeedTask.setGlassId(glassId);
        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_REQUEST_IN);
        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_IN_NEW);
        bigStorageCageFeedTask.setLine(line);
        bigStorageCageFeedTask.setTaskType(taskType);
        bigStorageCageFeedTask.setWidth(width);
@@ -321,7 +364,7 @@
    /**
     * 获取需要启动的线路:两条线都可启动 获取第一片玻璃版图id最小 版序最大的线路
     *
     * @return
     * @return 需要启动的线路
     */
    public Integer getStartLine() {
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
@@ -340,52 +383,135 @@
    /**
     * 计算任务表进片线路的目标格子,并启动任务
     */
    public boolean computeTargetByLine(Integer line, String d02GoAdress, String d05GoAdress) {
    public boolean computeTargetByLine(Integer line) {
        //1、获取任务表中的所有玻璃(指定线路且已经进卧转立完成)
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .eq(BigStorageCageFeedTask::getLine, line)
                .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP_ALL)
                .orderByAsc(BigStorageCageFeedTask::getId));
        //2、去笼子内查找是否可以继续存放的笼子
        List<String> glassIds = taskList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
        AtomicReference<Integer> temperingLayoutIdTemp = new AtomicReference<>(0);
        AtomicReference<Integer> temperingFeedSequenceTemp = new AtomicReference<>(0);
        AtomicReference<BigStorageDTO> bigStorageDTO = new AtomicReference<>(new BigStorageDTO());
        Map<String, GlassInfo> glassInfoMap = glassInfos.stream().collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
        List<BigStorageCageDetails> bigStorageCageDetailsList = new ArrayList<>();
        AtomicBoolean taskFlag = new AtomicBoolean(Boolean.TRUE);
        taskList.stream().forEach(e -> {
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            //按照版图信息获取进片笼子格子号
            GlassInfo info = glassInfoMap.get(e.getGlassId());
            BeanUtils.copyProperties(info, cageDetails);
            if (temperingLayoutIdTemp.equals(info.getTemperingLayoutId())
                    && temperingFeedSequenceTemp.equals(info.getTemperingFeedSequence() + 1)
                    && info.getWidth() <= bigStorageDTO.get().getWidth()) {
                bigStorageDTO.get().setWidth(bigStorageDTO.get().getWidth() - info.getWidth().intValue() - Const.BIG_STORAGE_GAP);
            } else {
                bigStorageDTO.set(bigStorageCageDetailsService.queryTargetSlotByTempering(info));
            }
            e.setTargetSlot(bigStorageDTO.get().getSlot());
            cageDetails.setSlot(bigStorageDTO.get().getSlot());
            cageDetails.setState(Const.GLASS_STATE_IN);
            temperingLayoutIdTemp.set(info.getTemperingLayoutId());
            temperingFeedSequenceTemp.set(info.getTemperingFeedSequence());
            bigStorageCageDetailsList.add(cageDetails);
            taskFlag.set(bigStorageCageFeedTaskService.updateById(e));
            if (!taskFlag.get()) {
                return;
            }
        });
        //3、更新进片任务表  遇到问题:无法批量更新,批量更新无法走指定从库
        //4、在详情表中加入进片玻璃信息
        bigStorageCageDetailsService.saveBatch(bigStorageCageDetailsList);
        if (taskFlag.get()) {
            String lineAddress = line.equals(Const.A09_OUT_TARGET_POSITION) ? d02GoAdress : d05GoAdress;
//            S7object.getinstance().plccontrol.writeWord(lineAddress, (short) 1);
        }
        return taskFlag.get();
        return computeIsTemperingTargetByLine(glassInfos, taskList, line);
    }
    /**
     * 是否钢化玻璃进笼目标位置
     *
     * @param glassInfos 当条线卧转立所有玻璃
     * @param taskList   当条线卧转立所有任务
     * @param line       任务是哪条线
     */
    private boolean computeIsTemperingTargetByLine(List<GlassInfo> glassInfos, List<BigStorageCageFeedTask> taskList, Integer line) {
        //1、将玻璃信息集合转为glassid为key的map
        Map<String, GlassInfo> glassInfoMap = glassInfos.stream()
                .collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
        for (BigStorageCageFeedTask e : taskList) {
            GlassInfo info = glassInfoMap.get(e.getGlassId());
            if (info == null) {
                continue;
            }
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            //2、获取目标格子信息
            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
            //3、更新大理片笼表剩余宽度
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - info.getWidth())
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            //4、更新进片任务表,目标格子及状态(状态改为2 电气扫到自行处理)  遇到问题:无法批量更新,批量更新无法走指定从库
            e.setTargetSlot(bigStorageDTO.getSlot());
//            e.setTaskType(Const.BIG_STORAGE_IN_RUN);
            bigStorageCageFeedTaskService.updateById(e);
            //5、将进片信息存入大理片笼详情表
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_IN);
            bigStorageCageDetailsService.save(cageDetails);
        }
        sendTaskListToPLC(taskList, line);
        return Boolean.TRUE;
    }
    private void sendTaskListToPLC(List<BigStorageCageFeedTask> taskList, Integer line) {
        S7control s7control = S7object.getinstance().plccontrol;
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getAddress();
        String outLine = line.equals(Const.A09_OUT_TARGET_POSITION) ? mesD03Address : mesD05Address;
        for (int i = 1; i <= taskList.size(); i++) {
            s7control.writeWord(plcMesObject.getPlcParameter("StartAddToImport" + i).getAddress(), taskList.get(i - 1).getLine());
            s7control.writeWord(plcMesObject.getPlcParameter("TargetAddToImport" + i).getAddress(), taskList.get(i - 1).getTargetSlot());
        }
        s7control.writeWord(outLine, 2);
        log.info("送片任务已发送完成,任务线路为:{},启动地址为{}", line, outLine);
    }
    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, Boolean isTempering) {
        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        for (T e : list) {
            if (bigStorageCageOutTaskList.size() > outCarMaxSize || e.getWidth() > remainWidth) {
                break;
            }
            remainWidth = remainWidth - (int) e.getWidth() - galssGap;
            if (isTempering) {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                        (int) e.getWidth() * 10, 0, 0, 1));
            } else {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
                        (int) e.getWidth() * 10, 0, 0, 1));
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                .in(BigStorageCageDetails::getGlassId, glassIds));
        //更新笼子内格子的剩余尺寸
        updateSlotRemain(list, glassIds);
        return Boolean.TRUE;
    }
    /**
     * 更新笼子内格子的剩余尺寸
     *
     * @param list
     * @param taskGlassIds
     * @param <T>
     */
    public <T extends BigStorageCageBaseInfo> void updateSlotRemain(List<T> list, List<String> taskGlassIds) {
        //获取需要出去(包括待出去的)的所有玻璃格子号
        List<Integer> slotList = list.stream().map(T::getSlot).distinct().collect(Collectors.toList());
        //获取待出去的玻璃信息(等下车出去的玻璃)
        Map<Integer, Double> slotRemainMap = list.stream().filter(e -> !taskGlassIds.contains(e.getGlassId()))
                .collect(Collectors.groupingBy(T::getSlot, Collectors.summingDouble(item -> item.getWidth() + galssGap)));
        if (CollectionUtils.isNotEmpty(slotRemainMap)) {
            //按照格子号更新剩余尺寸
            slotRemainMap.forEach((e, v) -> {
                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth - v)
                        .eq(BigStorageCage::getSlot, e));
            });
        }
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtils.isNotEmpty(slotList)) {
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                    .in(BigStorageCage::getSlot, slotList));
        }
    }
    public Boolean computeIsRun(int line, String glassId) {
        //获取卧转立剩余宽度
        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
        //获取玻璃信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        return sitToUpRemainWidth.getWidth() < glassInfo.getWidth();
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/controller/TemperingGlassInfoController.java
@@ -10,11 +10,7 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -38,15 +34,15 @@
    @ApiOperation("出片任务删除")
    @PostMapping("/deleteTemperingGlassInfo")
    public Result deleteTemperingGlassInfo(TemperingGlassInfo temperingGlassInfo) {
        temperingGlassInfoService.removeById(temperingGlassInfo);
    public Result deleteTemperingGlassInfo(@RequestBody TemperingGlassInfo temperingGlassInfo) {
        temperingGlassInfoService.removeById(temperingGlassInfo.getId());
        return Result.build(200,"删除成功",1);
    }
    @ApiOperation("出片任务破损")
    @ApiOperation("出片任务破损0/拿走1")
    @PostMapping("/damageTemperingGlassInfo")
    public Result damageTemperingGlassInfo(TemperingGlassInfo temperingGlassInfo) {
        bigStorageCageDetailsService.damageBigStorageCageDetails(temperingGlassInfo.getGlassId());
    public Result damageTemperingGlassInfo(@RequestBody TemperingGlassInfo temperingGlassInfo,int status) {
        bigStorageCageDetailsService.damageBigStorageCageDetails(temperingGlassInfo.getGlassId(),status);
        return Result.build(200,"破损成功",1);
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/entity/TemperingGlassInfo.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/mapper/TemperingGlassInfoMapper.java
File was deleted
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/service/TemperingGlassInfoService.java
@@ -1,6 +1,6 @@
package com.mes.temperingglass.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.base.MPJBaseService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import java.util.List;
@@ -13,9 +13,11 @@
 * @author zhoush
 * @since 2024-03-27
 */
public interface TemperingGlassInfoService extends IService<TemperingGlassInfo> {
public interface TemperingGlassInfoService extends MPJBaseService<TemperingGlassInfo> {
    public void addOutTask(List<TemperingGlassInfo> temperingGlassInfoList);
    boolean saveBatch(List<TemperingGlassInfo> list);
    void schedulingTask();
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/temperingglass/service/impl/TemperingGlassInfoServiceImpl.java
@@ -2,7 +2,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@@ -11,7 +10,6 @@
import com.mes.bigstorage.mapper.BigStorageCageDetailsMapper;
import com.mes.bigstorage.mapper.BigStorageCageMapper;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.mes.glassinfo.mapper.GlassInfoMapper;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.mapper.TemperingGlassInfoMapper;
import com.mes.temperingglass.service.TemperingGlassInfoService;
@@ -53,23 +51,28 @@
                temperingGlassInfo.setState(-1);
                baseMapper.updateById(temperingGlassInfo);
                log.info("3、修改钢化小片表任务状态");
                BigStorageCageOutTask bigStorageCageOutTask =new BigStorageCageOutTask();
                BigStorageCageOutTask bigStorageCageOutTask = new BigStorageCageOutTask();
                bigStorageCageOutTask.setId(temperingGlassInfo.getId());
            }else{
            } else {
                break;
            }
        }
    }
    @Override
    public boolean saveBatch(List<TemperingGlassInfo> list) {
        return baseMapper.saveBatch(list);
    }
    //调度
    @Override
    public void schedulingTask(){
    public void schedulingTask() {
        QueryWrapper<BigStorageCageDetails> detailsWrapper1 = Wrappers.query();
        detailsWrapper1.select("tempering_layout_id", "count(distinct slot)")
                .groupBy("tempering_layout_id");
        List<Map<String, Object>> temperingLayoutIdList = bigStorageCageDetailsMapper.selectMaps(detailsWrapper1);
        boolean key=false;
        boolean key = false;
        for (Map<String, Object> row : temperingLayoutIdList) {
            for (Map.Entry<String, Object> entry : row.entrySet()) {
                String temperingId = entry.getKey();
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/JsonFile/PlcCacheVerticalGlass.json
@@ -1,57 +1,377 @@
{
  "plcAddressBegin":"DB.0",
  "plcAddressLenght":"72",
  "dataType":"word",
  "parameteInfor":[
    {
      "codeId": "D01Request",
      "addressIndex":"0",
      "addressLenght":"2",
      "ratio":"1",
      "unit":"m/min"
    },
    {
      "codeId": "D01ID1",
      "addressIndex":"2",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04Request",
      "addressIndex":"8",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D04ID1",
      "addressIndex":"10",
      "addressLenght":"6",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D02Go",
      "addressIndex":"20",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    },
    {
      "codeId": "D05Go",
      "addressIndex":"22",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ,
    {
      "codeId": "DeviceStatus",
      "addressIndex":"70",
      "addressLenght":"2",
      "ratio":"1",
      "unit":""
    }
  ]
    "plcAddressBegin": "DB14.0",
    "plcAddressLenght": "938",
    "dataType": "word",
    "parameteInfor": [{
            "codeId": "D01ID",
            "addressIndex": "0",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D02ID",
            "addressIndex": "32",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID1",
            "addressIndex": "64",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID2",
            "addressIndex": "96",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID3",
            "addressIndex": "128",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID4",
            "addressIndex": "160",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID5",
            "addressIndex": "192",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ID6",
            "addressIndex": "224",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ID",
            "addressIndex": "256",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID1",
            "addressIndex": "288",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID2",
            "addressIndex": "328",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID3",
            "addressIndex": "352",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID4",
            "addressIndex": "384",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID5",
            "addressIndex": "416",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ID6",
            "addressIndex": "448",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID1",
            "addressIndex": "480",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID2",
            "addressIndex": "512",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID3",
            "addressIndex": "544",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID4",
            "addressIndex": "576",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID5",
            "addressIndex": "608",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01ID6",
            "addressIndex": "640",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID1",
            "addressIndex": "672",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID2",
            "addressIndex": "704",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID3",
            "addressIndex": "736",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID4",
            "addressIndex": "768",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID5",
            "addressIndex": "800",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02ID6",
            "addressIndex": "832",
            "addressLenght": "32",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03ToMES",
            "addressIndex": "874",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05ToMES",
            "addressIndex": "876",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D01ToMES",
            "addressIndex": "878",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D04ToMES",
            "addressIndex": "880",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD03",
            "addressIndex": "888",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD05",
            "addressIndex": "890",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToPLC",
            "addressIndex": "892",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport1",
            "addressIndex": "914",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport2",
            "addressIndex": "916",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport3",
            "addressIndex": "918",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport4",
            "addressIndex": "920",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport5",
            "addressIndex": "922",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "StartAddToImport6",
            "addressIndex": "924",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport1",
            "addressIndex": "926",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport2",
            "addressIndex": "928",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport3",
            "addressIndex": "930",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport4",
            "addressIndex": "932",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport5",
            "addressIndex": "934",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "TargetAddToImport6",
            "addressIndex": "936",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "deviceState",
            "addressIndex": "864",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E01State",
            "addressIndex": "866",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "E02State",
            "addressIndex": "868",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D03State",
            "addressIndex": "870",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "D05State",
            "addressIndex": "872",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD01",
            "addressIndex": "894",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        },
        {
            "codeId": "MESToD04",
            "addressIndex": "896",
            "addressLenght": "2",
            "ratio": "1",
            "unit": ""
        }
    ]
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-cz.yml
@@ -14,6 +14,10 @@
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        salve_hangzhoumes_1:
          url: jdbc:sqlserver://192.168.20.24:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-dev.yml
@@ -14,6 +14,10 @@
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        salve_hangzhoumes_1:
          url: jdbc:sqlserver://127.0.0.1:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application-prod.yml
@@ -14,6 +14,11 @@
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        salve_hangzhoumes_1:
          url: jdbc:sqlserver://10.153.19.150:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/application.yml
@@ -3,7 +3,7 @@
spring:
  profiles:
    active: dev
    active: prod
  application:
    name: cacheVerticalGlass
mybatis-plus:
@@ -12,4 +12,10 @@
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mes:
  sequence:
    order: false
    order: false
  minCount: 5
  carWidth: 5000   #大车宽度
  slotWidth: 5000   #大车宽度
  inCarMaxSize: 6     #进片大车最大存放玻璃数量
  outCarMaxSize: 1     #出片大车最大存放玻璃数量
  galssGap: 300      #玻璃间距
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageDetailsMapper.xml
New file
@@ -0,0 +1,74 @@
<?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 namespace="com.mes.bigstorage.mapper.BigStorageCageDetailsMapper">
    <resultMap id="temperingLayoutDTO" type="com.mes.bigstorage.entity.dto.TemperingLayoutDTO">
        <result column="engineer_id" property="engineerId"/>
        <result column="tempering_layout_id" property="temperingLayoutId"/>
        <result column="count" property="count"/>
        <result column="slot_count" property="slotCount"/>
    </resultMap>
    <resultMap id="slotSequenceDTO" type="com.mes.bigstorage.entity.dto.SlotSequenceDTO">
        <result column="engineer_id" property="engineerId"/>
        <result column="tempering_layout_id" property="temperingLayoutId"/>
        <result column="slot" property="slot"/>
        <result column="max_sequence" property="maxSequence"/>
        <result column="min_sequence" property="minSequence"/>
        <result column="remain_width" property="remainWidth"/>
    </resultMap>
    <select id="temperingIsAll" resultMap="temperingLayoutDTO">
        SELECT T2.*
        FROM (
                 SELECT T.ENGINEER_ID,
                        T.TEMPERING_LAYOUT_ID,
                        COUNT(T.TEMPERING_FEED_SEQUENCE) AS COUNT
                 FROM
                     GLASS_INFO T
                     LEFT JOIN DAMAGE T1
                 ON T.ENGINEER_ID = T1.ENGINEER_ID
                     AND T.GLASS_ID = T1.GLASS_ID
                 WHERE
                     T1.GLASS_ID IS NULL
                 GROUP BY
                     T.ENGINEER_ID,
                     T.TEMPERING_LAYOUT_ID
             ) T2
                 INNER JOIN (SELECT ENGINEER_ID, TEMPERING_LAYOUT_ID, COUNT(TEMPERING_FEED_SEQUENCE) AS COUNT
                             FROM BIG_STORAGE_CAGE_DETAILS
                             WHERE STATE in (100, 101, 102)
                             GROUP BY ENGINEER_ID, TEMPERING_LAYOUT_ID) T3 ON T2.ENGINEER_ID = T3.ENGINEER_ID
            AND T2.TEMPERING_LAYOUT_ID = T3.TEMPERING_LAYOUT_ID
            AND T2.COUNT = T3.COUNT LIMIT 1
    </select>
    <select id="queryTemperingOccupySlot" resultMap="temperingLayoutDTO">
        SELECT TEMPERING_LAYOUT_ID,
               COUNT(DISTINCT SLOT) as SLOT_COUNT
        FROM BIG_STORAGE_CAGE_DETAILS
        WHERE STATE = 100
        GROUP BY ENGINEER_ID,
                 TEMPERING_LAYOUT_ID
        HAVING SLOT_COUNT &gt;= #{count} LIMIT 1
    </select>
    <select id="queryGlassMaxAndMin" resultMap="slotSequenceDTO">
        SELECT T.*,
               T1.REMAIN_WIDTH
        FROM (
                 SELECT ENGINEER_ID,
                        TEMPERING_LAYOUT_ID,
                        SLOT,
                        MAX(TEMPERING_FEED_SEQUENCE) AS MAX_SEQUENCE,
                        MIN(TEMPERING_FEED_SEQUENCE) AS MIN_SEQUENCE
                 FROM BIG_STORAGE_CAGE_DETAILS
                 WHERE ENGINEER_ID = #{engineerId}
                   AND TEMPERING_LAYOUT_ID = #{temperingLayoutId}
                 GROUP BY ENGINEER_ID,
                          TEMPERING_LAYOUT_ID,
                          SLOT
             ) T
                 INNER JOIN BIG_STORAGE_CAGE T1 ON T.SLOT = T1.SLOT
        ORDER BY T.MAX_SEQUENCE DESC
    </select>
</mapper>
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageFeedTaskMapper.xml
@@ -2,7 +2,12 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mes.bigstoragetask.mapper.BigStorageCageFeedTaskMapper">
    <select id="querySitToUpGlass" resultType="java.lang.String">
    <resultMap id="bigStorageDTO" type="com.mes.bigstorage.entity.BigStorageDTO">
        <result column="REMAIN_WIDTH" property="width"/>
        <result column="GLASS_COUNT" property="glassCount"/>
    </resultMap>
    <select id="querySitToUpGlass" resultType="java.lang.Integer">
        select t.line
        from (
                 select line,
@@ -10,9 +15,17 @@
                        SUM(case task_state when 2 then 1 else 0 end) as real_count
                 from big_storage_cage_feed_task
                 where task_state in (1, 2)
                   and (target_slot = 0 or target_slot is null)
                 group by line
             ) t
        where t.total_count = t.real_count
    </select>
    <select id="querySitToUpRemainWidth" resultMap="bigStorageDTO">
        SELECT cast(5000 - sum(width + 20) as INT) as REMAIN_WIDTH,
               count(glass_id)                     as GLASS_COUNT
        FROM big_storage_cage_feed_task
        WHERE line = #{line}
          AND task_state in (1, 2)
    </select>
</mapper>
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageOutTaskMapper.xml
New file
@@ -0,0 +1,14 @@
<?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 namespace="com.mes.bigstoragetask.mapper.BigStorageCageOutTaskMapper">
    <insert id="saveBatch">
        INSERT INTO big_storage_cage_out_task ( glass_id, start_slot, end_slot, train_number, serial_number, task_state
        )
        values
        <foreach collection="list" item="item" separator=",">
            (#{item.glassId}, #{item.startSlot}, #{item.endSlot}, #{item.trainNumber}, #{item.serialNumber},
            #{item.taskState})
        </foreach>
    </insert>
</mapper>
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/test/java/com/mes/CacheVerticalGlassModuleApplicationTest.java
@@ -1,5 +1,6 @@
package com.mes;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.common.config.Const;
import com.mes.job.PlcStorageCageTask;
@@ -26,6 +27,8 @@
    BigStorageCageService bigStorageCageService;
    @Autowired
    PlcStorageCageTask plcStorageCageTask;
    @Autowired
    BigStorageCageDetailsService bigStorageCageDetailsService;
    @Test
    public void testFindPath() {
@@ -33,28 +36,50 @@
    }
    @Test
    public void outGlass() {
        log.info("完整路径:{}", bigStorageCageService.outGlass());
    }
    @Test
    public void plcToHomeEdgOutTask() {
        plcStorageCageTask.plcToHomeEdgOutTask();
    }
    @Test
    public void plcToHomeEdgFreeCarTask() {
        plcStorageCageTask.plcToHomeEdgFreeCarTask();
    }
    @Test
    public void plcStorageCageTask() {
        plcStorageCageTask.plcToHomeEdgScan();
    }
    @Test
    public void computeTargetByLine() {
//        log.info("获取大理片笼信息:{}",bigStorageCageService.querybigStorageCageDetail());
        plcStorageCageTask.computeTargetByLine(2001, "", "");
        plcStorageCageTask.computeTargetByLine(2001);
    }
    @Test
    public void judgeGlassTypeStatus() {
//        log.info("获取大理片笼信息:{}",bigStorageCageService.querybigStorageCageDetail());
        plcStorageCageTask.judgeGlassTypeStatus("P24060403|6|7", Const.A09_OUT_TARGET_POSITION);
        plcStorageCageTask.judgeGlassTypeStatus("P24060403|6|7", Const.A09_OUT_TARGET_POSITION, "mesD03Address");
    }
    @Test
    public void getStartLine() {
//        log.info("获取大理片笼信息:{}",bigStorageCageService.querybigStorageCageDetail());
        Integer startLine = plcStorageCageTask.getStartLine();
        log.info("---------{}", startLine);
    }
    @Test
    public void selectBigStorageCageUsage() {
//        bigStorageCageService.querybigStorageCageDetail(1);
        log.info("获取大理片笼信息:{}", bigStorageCageService.selectBigStorageCageUsage());
    }
    @Test
    public void selectBigStorageCageDetails() {
        log.info("获取大理片笼信息:{}", bigStorageCageDetailsService.selectBigStorageCageDetails("P24060403|3|6"));
    }
}
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/engineering/entity/Engineering.java
@@ -40,17 +40,17 @@
    /**
     * 平均利用率
     */
    private Double avgAvailability;
    private double avgAvailability;
    /**
     * 有效利用率
     */
    private Double validAvailability;
    private double validAvailability;
    /**
     * 尾片利用率
     */
    private Double lastAvailability;
    private double lastAvailability;
    /**
     * 状态
@@ -65,7 +65,7 @@
    /**
     * 小片总面积
     */
    private Double glassTotalArea;
    private double glassTotalArea;
    /**
     * 计划原片总数
@@ -75,7 +75,7 @@
    /**
     * 计划原片总面积
     */
    private Double planPatternTotalArea;
    private double planPatternTotalArea;
    /**
     * 实际原片总数
@@ -85,7 +85,7 @@
    /**
     * 实际原片总面积
     */
    private Double realityPatternTotalArea;
    private double realityPatternTotalArea;
    /**
     * 膜系id
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/engineering/entity/OptimizeEngineering.java
@@ -25,17 +25,17 @@
    /**
     * 平均利用率
     */
    private Double avgCutPct;
    private double avgCutPct;
    /**
     * 有效利用率
     */
    private Double validCutPct;
    private double validCutPct;
    /**
     * 尾片利用率
     */
    private Double lastCutPct;
    private double lastCutPct;
    /**
     * 状态
@@ -49,7 +49,7 @@
    /**
     * 小片总面积
     */
    private Double glassTotalArea;
    private double glassTotalArea;
    /**
     * 计划原片总数
     */
@@ -57,7 +57,7 @@
    /**
     * 计划原片总面积
     */
    private Double rawStockArea;
    private double rawStockArea;
    /**
     * 实际原片总数
     */
@@ -65,11 +65,11 @@
    /**
     * 实际原片总面积
     */
    private Double actualStockArea;
    private double actualStockArea;
    /**
     * 膜系
     */
    private  String glassType;
    private String glassType;
    /**
     * 备注
     */
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/uppattenusage/entity/OptimizeUpPattenUsage.java
@@ -25,17 +25,17 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double glassThickness;
    private double glassThickness;
    /**
     * 原片版图片序
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/uppattenusage/service/impl/UpPattenUsageServiceImpl.java
@@ -19,7 +19,6 @@
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -67,8 +66,8 @@
        List<OptimizeUpPattenUsage> upPattenUsageList = null;
        if (engineeringId != null) {
            upPattenUsageList = optimizeProjectMapper.selectJoinList(OptimizeUpPattenUsage.class, new MPJQueryWrapper<OptimizeProject>()
                    .select("t.project_no,t.glass_type,b.realwidth as width,b.realheight as height ,REGEXP_REPLACE(t.glass_thickness,'\\D','')as glass_thickness,b.stock_id")
                    .leftJoin("optimize_layout b on t.project_no=b.project_no")
                    .select("t.project_no,t.glass_type,b.o_width as width,b.o_height as height ,REGEXP_REPLACE(t.glass_thickness,'\\D','')as glass_thickness,b.stock_number")
                    .leftJoin("optimize_detail b on t.project_no=b.project_no")
                    .eq("b.project_no", engineeringId));
        }
        // 创建一个 List 用于保存映射后的实体对象
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/workstation/entity/UpWorkstation.java
@@ -50,17 +50,17 @@
    /**
     * 原片宽
     */
    private Double patternWidth;
    private double patternWidth;
    /**
     * 原片高
     */
    private Double patternHeight;
    private double patternHeight;
    /**
     * 原片厚度
     */
    private Double patternThickness;
    private double patternThickness;
    /**
     * 膜系
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/workstation/mapper/LoadGlassMapper.java
File was deleted
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-cz.yml
@@ -14,6 +14,11 @@
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        sd:
            url: jdbc:mysql://192.168.1.199:3306/sd?serverTimezone=GMT%2b8
            username: root
            password: beibo.123/
            driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-dev.yml
@@ -14,16 +14,11 @@
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
#        hangzhoumes:
#          url: jdbc:mysql://10.153.19.150:3306/hangzhoumes?serverTimezone=GMT%2b8
#          username: root
#          password: beibo.123/
#          driver-class-name: com.mysql.cj.jdbc.Driver
#        pp:
#          url: jdbc:mysql://10.153.19.150:3306/pp?serverTimezone=GMT%2b8
#          username: root
#          password: beibo.123/
#          driver-class-name: com.mysql.cj.jdbc.Driver
        sd:
          url: jdbc:mysql://127.0.0.1:3306/sd?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/LoadGlassModule/src/main/resources/application-prod.yml
@@ -14,6 +14,11 @@
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        sd:
            url: jdbc:mysql://10.153.19.150:3306/sd?serverTimezone=GMT%2b8
            username: root
            password: beibo.123/
            driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/LoadGlassModule/src/test/java/com/mes/ApplicationTest.java
@@ -30,4 +30,5 @@
        List<OptimizeDetail> list = optimizationDetailService.list();
        System.out.println("获取记录数:" + list.size());
    }
}
hangzhoumesParent/moduleService/LoadGlassModule/src/test/java/com/mes/LoadGlassModuleApplicationTest.java
@@ -1,11 +1,17 @@
package com.mes;
import com.mes.engineering.entity.Engineering;
import com.mes.engineering.service.EngineeringService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.order.entity.Orderdetail;
import com.mes.order.entity.Orders;
import com.mes.order.service.OrdersService;
import com.mes.pp.entity.OptimizeProject;
import com.mes.pp.entity.request.AwaitingRepair;
import com.mes.pp.entity.request.OptimizeRequest;
import com.mes.pp.entity.request.Reportingdamage;
import com.mes.pp.service.OptimizeProjectService;
import com.mes.pp.service.ReportingWorkService;
import com.mes.uppattenusage.entity.UpPattenUsage;
import com.mes.uppattenusage.service.impl.UpPattenUsageServiceImpl;
import com.mes.workstation.entity.UpWorkstation;
@@ -16,7 +22,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.List;
@@ -40,6 +45,10 @@
    private UpWorkstationService workstationService;
    @Autowired
    private OptimizeProjectService optimizeProjectService;
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private ReportingWorkService reportingWorkService;
    @Test
    public void test() {
//        List<OptimizeProject> list = optimizeProjectMapper.saveProject("P24032204");
@@ -109,5 +118,54 @@
        boolean isOver= upPattenUsageService.updateGlassState(upPattenUsage);
        log.info("更改是否成功{}",isOver);
    }
    @Test
    public void test2() {
        List<Orders> list = ordersService.selectOrders();
        System.out.println("获取记录数:" + list);
    }
    @Test
    public void test3() {
        Orders orders = new Orders();
        orders.setOrderId("P24051103");
        List<Orderdetail> list = ordersService.selectOrderdetail(orders);
        System.out.println("订单详细数据:" + list);
    }
    @Test
    public void test4() {
        //获取工序加工次破数量
        Reportingdamage reportingdamage = new Reportingdamage();
        reportingdamage.setThisProcess("磨边");
        reportingdamage.setDeviceName("快速磨");
        reportingdamage.setReportingWorkTime("2024-05-22");
        List<Reportingdamage> list = reportingWorkService.selectDamage(reportingdamage);
        System.out.println("订单详细数据:" + list);
    }
    @Test
    public void test5() {
        //获取次破未补信息
        List<AwaitingRepair> list = reportingWorkService.selectAwaitingRepair();
        System.out.println("获取记录数:" + list);
    }
    @Test
    public void test6() {
        //获取次破未补信息
       List<OptimizeProject> list=optimizeProjectService.getDoingTask();
        System.out.println("获取正在进行的工程:" + list);
    }
    @Test
    public void test7() {
        //获取次破未补信息
        List<GlassInfo> list=glassInfoService.selectGlassInfo("P24062706");
        System.out.println("工程:"+list);
    }
    @Test
    public void test8() {
        //获取次破未补信息
        UpPattenUsage upPattenUsage=new UpPattenUsage();
        upPattenUsage.setEngineeringId("P24062706");
        List<UpPattenUsage> list=upPattenUsageService.selectSaveUpPattenUsage("P24062706");
        System.out.println("工程:"+list);
    }
}
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcScreenTask.java
New file
@@ -0,0 +1,88 @@
package com.mes.job;
import cn.hutool.json.JSONObject;
import com.mes.order.entity.Orders;
import com.mes.order.service.OrdersService;
import com.mes.pp.entity.OptimizeProject;
import com.mes.pp.entity.request.AwaitingRepair;
import com.mes.pp.entity.request.Reportingdamage;
import com.mes.pp.service.OptimizeProjectService;
import com.mes.pp.service.ReportingWorkService;
import com.mes.tools.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
 * @author SNG-010
 */
@Component
@Slf4j
public class PlcScreenTask {
    @Autowired
    private ReportingWorkService reportingWorkService;
    @Autowired
    private  OptimizeProjectService optimizeProjectService;
    @Autowired
    private OrdersService ordersService;
    /**
     * fixedRate : 上一个调用开始后再次调用的延时(不用等待上一次调用完成)
     * fixedDelay : 上一个调用结束后再次调用的延时
     */
    @Scheduled(fixedDelay = 2000)
    public void screenHome(){
        JSONObject jsonObject = new JSONObject();
        //正在等待进片的玻璃
        Reportingdamage reportingdamage = new Reportingdamage();
        reportingdamage.setReportingWorkTime("2024-05-11");
        //获取切割信息
        reportingdamage.setThisProcess("切割");
        List<Reportingdamage> cutting = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("cutting", cutting);
        //获取磨边信息
        reportingdamage.setThisProcess("磨边");
        List<Reportingdamage> edging = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("edging", edging);
        //获取钢化信息
        reportingdamage.setThisProcess("钢化");
        List<Reportingdamage> tempering = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("tempering", tempering);
        //获取夹胶信息
        reportingdamage.setThisProcess("夹胶");
        List<Reportingdamage> doubling = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("doubling", doubling);
        //获取中空信息
        reportingdamage.setThisProcess("中空");
        List<Reportingdamage> hollow = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("hollow", hollow);
        //获取包装信息
        reportingdamage.setThisProcess("包装");
        List<Reportingdamage> packaging = reportingWorkService.selectDamage(reportingdamage);
        jsonObject.append("packaging", packaging);
        //获取次破未补信息
        List<AwaitingRepair>awaitingRepairs = reportingWorkService.selectAwaitingRepair();
        jsonObject.append("awaitingRepairs", awaitingRepairs);
        //获取正在进行的工程
        List<OptimizeProject>optimizeProjects= optimizeProjectService.getDoingTask();
        jsonObject.append("DoingTask", optimizeProjects);
        //获取当前订单
        List<Orders>orders=ordersService.selectOrders();
        jsonObject.append("orders", orders);
        ArrayList<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("screen");
        if (sendwServer != null) {
            for (WebSocketServer webserver : sendwServer) {
                if (webserver != null) {
                    webserver.sendMessage(jsonObject.toString());
                } else {
                    log.info("Home is closed");
                }
            }
        }
    }
}
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcTemperingGlassTask.java
@@ -1,9 +1,7 @@
package com.mes.job;
import cn.hutool.json.JSONObject;
import com.mes.temperingglass.service.TemperingAgoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingAgoService;
import com.mes.tools.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +26,7 @@
     */
    @Scheduled(fixedDelay = 1000)
    public void loadGlassHome(){
    public void temperingGlassHome(){
        JSONObject jsonObject = new JSONObject();
        //正在等待进片的玻璃
        List<TemperingGlassInfo> waitingGlass = temperingAgoService.selectWaitingGlass();
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-cz.yml
@@ -9,9 +9,8 @@
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        salve_hangzhoumes:
          url: jdbc:sqlserver://192.168.10.2:1433;databasename=hangzhoumes
          url: jdbc:sqlserver://192.168.20.24:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-dev.yml
@@ -4,16 +4,36 @@
      primary: hangzhoumes #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
      datasource:
#        hangzhoumes:
#          url: jdbc:mysql://127.0.0.1:3306/hangzhoumes?serverTimezone=GMT%2b8
#          username: root
#          password: beibo.123/
#          driver-class-name: com.mysql.cj.jdbc.Driver
#        salve_hangzhoumes:
#          url: jdbc:sqlserver://127.0.0.1:1433;databasename=hangzhoumes
#          username: sa
#          password: beibo.123/
#          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        hangzhoumes:
          url: jdbc:mysql://127.0.0.1:3306/hangzhoumes?serverTimezone=GMT%2b8
          url: jdbc:mysql:10.153.19.150:3306/hangzhoumes?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        salve_hangzhoumes:
          url: jdbc:sqlserver://127.0.0.1:1433;databasename=hangzhoumes
          url: jdbc:sqlserver://10.153.19.150:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        pp:
          url: jdbc:mysql://10.153.19.150:3306/pp?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        sd:
          url: jdbc:mysql://10.153.19.150:3306/sd?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application-prod.yml
@@ -15,6 +15,16 @@
            username: sa
            password: beibo.123/
            driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        pp:
          url: jdbc:mysql://10.153.19.150:3306/pp?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        sd:
          url: jdbc:mysql://10.153.19.150:3306/sd?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/resources/application.yml
@@ -2,7 +2,7 @@
  port: 8084
spring:
  profiles:
    active: cz
    active: prod
  application:
    name: temperingGlass
mybatis-plus:
hangzhoumesParent/moduleService/TemperingGlassModule/src/test/java/com/mes/TemperingApplicationTest.java
@@ -1,60 +1,60 @@
//package com.mes;
//
//import com.mes.temperingglass.entity.TemperingGlassInfo;
//import com.mes.temperingglass.service.TemperingAgoService;
//import lombok.extern.slf4j.Slf4j;
//import org.junit.Test;
//import org.junit.runner.RunWith;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.context.junit4.SpringRunner;
//
//import java.util.Arrays;
//import java.util.List;
//
///**
// * @Author : zhoush
// * @Date: 2024/3/27 16:37
// * @Description:
// */
//@Slf4j
//@RunWith(SpringRunner.class)
//@SpringBootTest(classes = TemperingGlassModuleApplication.class)
//public class TemperingApplicationTest {
//
//    @Autowired
//    private TemperingAgoService temperingAgoService;
//
//
//    @Test
//    public void testFindPa() {
//        List<TemperingGlassInfo> glass = temperingAgoService.selectIntoGlass(12);
//        log.info("进炉中的玻璃:{}", Arrays.asList(glass));
//    }
//    @Test
//    public void testFindPa2() {
//        List<TemperingGlassInfo> glass = temperingAgoService.selectOutGlass();
//        log.info("已出中的玻璃:{}", Arrays.asList(glass));
//    }
//
//    @Test
//    public void testFindPa3() {
//        List<TemperingGlassInfo> glass = temperingAgoService.selectWaitingGlass();
//        log.info("等待中的玻璃:{}", Arrays.asList(glass));
//    }
//    @Test
//    public void testFindPa4() {
//        List<TemperingGlassInfo> glass = temperingAgoService.selectOverGlass();
//        log.info("等待中的玻璃:{}", Arrays.asList(glass));
//    }
//    @Test
//    public void testFindPa5() {
//        List<TemperingGlassInfo> layoutId = temperingAgoService.selectLayoutId();
//        //进炉中的玻璃
//        log.info("版图id:{}", Arrays.asList(layoutId.get(0).getTemperingLayoutId()));
//        List<TemperingGlassInfo> intoGlass = temperingAgoService.selectIntoGlass(layoutId.get(0).getTemperingLayoutId());
//        log.info("玻璃版图id:{}", Arrays.asList(intoGlass));
//        List<TemperingGlassInfo> intoGlass2 = temperingAgoService.selectIntoGlass(layoutId.get(1).getTemperingLayoutId());
//        log.info("玻璃版图id:{}", Arrays.asList(intoGlass2));
//    }
//}
package com.mes;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingAgoService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.List;
/**
 * @Author : zhoush
 * @Date: 2024/3/27 16:37
 * @Description:
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TemperingGlassModuleApplication.class)
public class TemperingApplicationTest {
    @Autowired
    private TemperingAgoService temperingAgoService;
    @Test
    public void testFindPa() {
        List<TemperingGlassInfo> glass = temperingAgoService.selectIntoGlass(12);
        log.info("进炉中的玻璃:{}", Arrays.asList(glass));
    }
    @Test
    public void testFindPa2() {
        List<TemperingGlassInfo> glass = temperingAgoService.selectOutGlass();
        log.info("已出中的玻璃:{}", Arrays.asList(glass));
    }
    @Test
    public void testFindPa3() {
        List<TemperingGlassInfo> glass = temperingAgoService.selectWaitingGlass();
        log.info("等待中的玻璃:{}", Arrays.asList(glass));
    }
    @Test
    public void testFindPa4() {
        List<TemperingGlassInfo> glass = temperingAgoService.selectOverGlass();
        log.info("等待中的玻璃:{}", Arrays.asList(glass));
    }
    @Test
    public void testFindPa5() {
        List<TemperingGlassInfo> layoutId = temperingAgoService.selectLayoutId();
        //进炉中的玻璃
        log.info("版图id:{}", Arrays.asList(layoutId.get(0).getTemperingLayoutId()));
        List<TemperingGlassInfo> intoGlass = temperingAgoService.selectIntoGlass(layoutId.get(0).getTemperingLayoutId());
        log.info("玻璃版图id:{}", Arrays.asList(intoGlass));
        List<TemperingGlassInfo> intoGlass2 = temperingAgoService.selectIntoGlass(layoutId.get(1).getTemperingLayoutId());
        log.info("玻璃版图id:{}", Arrays.asList(intoGlass2));
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/pom.xml
@@ -24,12 +24,6 @@
            <version>2.8.9</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>
    <properties>
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/AppRunnerConfig.java
@@ -1,6 +1,7 @@
package com.mes;
//import com.mes.common.S7object;
import com.mes.common.S7object;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
@@ -13,14 +14,12 @@
@Slf4j
@Component
@Order(1)
public class AppRunnerConfig implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("启动完成");
        //S7object.getinstance().start();
        S7object.getinstance().start();
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/common/S7object.java
@@ -14,7 +14,7 @@
public class S7object extends Thread {
    public S7control plccontrol; // PLC通讯类实例
    private EPlcType plcType = EPlcType.S1200; // 西门子PLC类型
    private String ip = "192.168.10.1"; // plc ip地址
    private String ip = "192.168.30.100"; // plc ip地址
    private int port = 102; // plc 端口号
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/controller/DownGlassTaskController.java
@@ -1,9 +1,13 @@
package com.mes.downglassinfo.controller;
import io.swagger.annotations.Api;
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.utils.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -20,5 +24,14 @@
@RequestMapping("/downGlassTask")
public class DownGlassTaskController {
    @Autowired
    DownGlassInfoService downGlassInfoService;
    @PostMapping("/generateOutGlassTask")
    @ApiOperation(value = "生成出片任务", notes = "生成出片任务")
    public Result<Boolean> generateOutGlassTask(@RequestBody DownStorageCageDetails downStorageCageDetails) {
        return Result.success(downGlassInfoService.generateOutGlassTask(downStorageCageDetails.getGlassId()));
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/entity/DownGlassInfo.java
@@ -1,10 +1,10 @@
package com.mes.downglassinfo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.Id;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@@ -26,13 +26,18 @@
    /**
     * 下片玻璃信息表id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 流程卡号
     */
    private String flowCardId;
    /**
     * 层号
     */
    private Integer layer;
    /**
     * 顺序
@@ -42,17 +47,17 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 膜系
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/entity/DownGlassTask.java
@@ -1,5 +1,6 @@
package com.mes.downglassinfo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -24,18 +25,24 @@
    /**
     * id
     */
    @TableId(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 玻璃id
     */
    private String glassId;
    /**
     * 起始
     */
    private String startCell;
    private Integer startCell;
    /**
     * 目标
     */
    private String endCell;
    private Integer endCell;
    /**
     * 任务类型 1:进   2:出
@@ -45,12 +52,12 @@
    /**
     * 宽
     */
    private Double width;
    private Integer width;
    /**
     * 高
     */
    private Double height;
    private Integer height;
    /**
     * 膜系
@@ -60,22 +67,21 @@
    /**
     * 厚度
     */
    private Double thickness;
    private Integer thickness;
    /**
     * 流程卡号
     */
    private String flowCardId;
    /**
     * 层号
     */
    private int layer;
    /**
     * 任务状态 0 未开始  1正在进行   2完成
     */
    private Integer taskStauts;
    /**
     * 玻璃id
     */
    private String glassId;
    /**
     * 创建时间
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/mapper/DownGlassInfoMapper.java
@@ -2,11 +2,19 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downworkstation.entity.dto.DownGlassInfoDTO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface DownGlassInfoMapper extends BaseMapper<DownGlassInfo> {
    DownGlassInfoDTO queryDownGlassMaxLayer(@Param(value = "flowCardId") String flowCardId);
    Integer queryMaxSequence(@Param(value = "flowCardId") String flowCardId, @Param(value = "layer") int layer);
    List<DownGlassInfoDTO> queryWorkStationIsIn(@Param(value = "isDownload") Boolean isDownload);
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/DownGlassInfoService.java
@@ -2,6 +2,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downworkstation.entity.dto.DownGlassInfoDTO;
import java.util.List;
public interface DownGlassInfoService extends IService<DownGlassInfo> {
@@ -10,7 +13,7 @@
     * @param flowCardId
     * @return // 根据流程卡号查询最大序号
     */
    Integer getMaxSequenceByFlowCardId(String flowCardId);
    Integer getMaxSequenceByFlowCardId(String flowCardId, int layer);
    /**
     * @param downGlassInfo 插入下片信息
@@ -18,4 +21,23 @@
    void insertDownGlassInfo(DownGlassInfo downGlassInfo);
    DownGlassInfoDTO queryDownGlassMaxLayer(String flowCardId);
    Integer queryMaxSequence(String flowCardId, int layer);
    /**
     * 获取架子绑定 流程卡的玻璃信息(已落架/未落架)
     *
     * @param isDownload true/false
     * @return
     */
    List<DownGlassInfoDTO> queryWorkStationIsIn(Boolean isDownload);
    /**
     * 生成出片任务
     *
     * @param glassId
     * @return
     */
    boolean generateOutGlassTask(String glassId);
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/impl/DownGlassInfoServiceImpl.java
@@ -1,21 +1,41 @@
package com.mes.downglassinfo.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.common.config.Const;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downglassinfo.mapper.DownGlassInfoMapper;
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.downstorage.service.DownStorageCageDetailsService;
import com.mes.downworkstation.entity.dto.DownGlassInfoDTO;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.job.DownLoadCacheGlassTask;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DownGlassInfoServiceImpl extends ServiceImpl<DownGlassInfoMapper, DownGlassInfo> implements DownGlassInfoService {
    // 根据流程卡号查询最大序号
    @Autowired
    DownLoadCacheGlassTask downLoadCacheGlassTask;
    @Autowired
    DownStorageCageDetailsService downStorageCageDetailsService;
    /**
     * 根据流程卡号查询最大序号
     */
    @Override
    public Integer getMaxSequenceByFlowCardId(String flowCardId) {
    public Integer getMaxSequenceByFlowCardId(String flowCardId, int layer) {
        LambdaQueryWrapper<DownGlassInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(DownGlassInfo::getFlowCardId, flowCardId)
                .eq(DownGlassInfo::getLayer, layer)
                .select(DownGlassInfo::getSequence)
                .orderByDesc(DownGlassInfo::getSequence)
                .last("LIMIT 1");
@@ -24,14 +44,42 @@
        return downGlassInfo != null ? downGlassInfo.getSequence() : 0;
    }
    @Override
    public void insertDownGlassInfo(DownGlassInfo downGlassInfo) {
        baseMapper.insert(downGlassInfo);
    }
    @Override
    public DownGlassInfoDTO queryDownGlassMaxLayer(String flowCardId) {
        return baseMapper.queryDownGlassMaxLayer(flowCardId);
    }
    @Override
    public Integer queryMaxSequence(String flowCardId, int layer) {
        return baseMapper.queryMaxSequence(flowCardId, layer);
    }
    @Override
    public List<DownGlassInfoDTO> queryWorkStationIsIn(Boolean isDownload) {
        return baseMapper.queryWorkStationIsIn(isDownload);
    }
    @Override
    public boolean generateOutGlassTask(String glassId) {
        //更新卧式理片笼内玻璃状态
        downStorageCageDetailsService.update(new LambdaUpdateWrapper<DownStorageCageDetails>()
                .set(DownStorageCageDetails::getState, Const.GLASS_STATE_OUT).eq(DownStorageCageDetails::getGlassId, glassId));
        DownStorageCageDetails details = downStorageCageDetailsService.getOne(new LambdaQueryWrapper<DownStorageCageDetails>()
                .eq(DownStorageCageDetails::getGlassId, glassId));
        //生成下片信息
        DownGlassInfo downGlassInfo = new DownGlassInfo();
        BeanUtils.copyProperties(details, downGlassInfo);
        //获取当前流程卡最大片序
        downGlassInfo.setSequence(this.getMaxSequenceByFlowCardId(details.getFlowCardId(), details.getLayer()) + 1);
        this.save(downGlassInfo);
        //生成任务信息 并向plc发送出片任务
        GlassInfo glassInfo = new GlassInfo();
        BeanUtils.copyProperties(details, glassInfo);
        return downLoadCacheGlassTask.initDownGlassTask(glassInfo, details.getSlot(), 3001, 2);
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downglassinfo/service/impl/DownGlassTaskServiceImpl.java
@@ -5,14 +5,21 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downglassinfo.mapper.DownGlassInfoMapper;
import com.mes.downglassinfo.mapper.DownGlassTaskMapper;
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.downworkstation.entity.DownWorkstation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -22,17 +29,37 @@
 * @author zhoush
 * @since 2024-04-07
 */
@Slf4j
@Service
public class DownGlassTaskServiceImpl extends ServiceImpl<DownGlassTaskMapper, DownGlassTask> implements DownGlassTaskService {
    @Autowired
    private DownGlassInfoService downGlassInfoService; // MySQL Mapper
    @Autowired
    private DownGlassTaskMapper downGlassTaskMapper; // SQL Server Mapper
    @Override
    public List<DownGlassTask> getUnloadingTaskState() {
        log.info("排除已经下片的出片或直通任务状态为1的任务");
        // Step 1: 从 MySQL 中获取玻璃 ID 列表
        // Step 2: 从 SQL Server 中过滤掉这些玻璃 ID 并查询任务
        QueryWrapper<DownGlassTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_stauts", 0).eq("task_type", 2).or().eq("task_stauts", 3);
        queryWrapper.eq("task_stauts", 1)
                .and(qw -> qw.eq("task_type", 2).or().eq("task_type", 3));
        List<DownGlassInfo> excludedGlassIds = downGlassInfoService.list();
        if (!excludedGlassIds.isEmpty()) {
            queryWrapper.notIn("glass_id", excludedGlassIds.stream().map(DownGlassInfo::getGlassId).collect(Collectors.toList()));
        }
        log.info(String.valueOf(excludedGlassIds));
        return baseMapper.selectList(queryWrapper);
    }
    @Override
    public void updateTaskState(String id) {
        UpdateWrapper<DownGlassTask> updateWrapper = new UpdateWrapper<>();
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/controller/DownStorageCageDetailsController.java
@@ -69,8 +69,15 @@
//
    @ApiOperation("修改玻璃状态   功能:对笼内栅格玻璃进行【破损/拿走】  ")
    @PostMapping("/ReportStatus")
    @ResponseBody
    public Result edgReportStatus(@RequestBody Map<String, String> arguments) {
        String downStorageCageDetailsId=arguments.get("glassId");
        int controlsId=Integer.valueOf(arguments.get("controlsId"));
        boolean isSucess=downStorageCageDetailsService.identWorn(downStorageCageDetailsId,controlsId);
        return Result.build(200,"【破损/拿走】成功",1);
    }
    // Other CRUD operations can be defined here
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/entity/DownStorageCage.java
@@ -50,7 +50,7 @@
     */
    @ApiModelProperty(value = "启用状态", position = 5)
    @TableField("enable_state")
    private String enableState;
    private Integer enableState;
    /**
     * 剩余
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/entity/DownStorageCageDetails.java
@@ -60,17 +60,17 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 钢化版图id
@@ -96,6 +96,14 @@
     * 玻璃间隙
     */
    private Integer gap;
    /**
     * 总层数
     */
    private Integer totalLayer;
    /**
     * 层数
     */
    private Integer layer;
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/mapper/DownStorageCageDetailsMapper.java
@@ -1,13 +1,8 @@
package com.mes.downstorage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.glassinfo.entity.GlassInfo;
import org.apache.ibatis.annotations.*;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
@@ -20,4 +15,5 @@
@Mapper
public interface DownStorageCageDetailsMapper extends MPJBaseMapper<DownStorageCageDetails> {
    DownStorageCageDetails getGlassInfoMaxCount();
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/DownStorageCageDetailsService.java
@@ -56,7 +56,27 @@
    /**
     * @param start
     * @param end
     * @return   根据传入的料架号 查询符合按照流程卡中顺序出片的小片
     */
    List<DownStorageCageDetails> CacheOut2(int start, int end);
//    /**
//     * @return 直通查询
//     */
//    List<GlassInfo>  DirectConnection();
    /**
     * @return 直通查询
     */
    List<GlassInfo>  DirectConnection();
    boolean DirectConnection(GlassInfo glassInfo);
    DownStorageCageDetails getGlassInfoMaxCount();
    /**
     * @param glassId
     * @param ControlsId
     * @return  破损
     */
    boolean identWorn(String glassId, int ControlsId);
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/DownStorageCageService.java
@@ -1,6 +1,5 @@
package com.mes.downstorage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.base.MPJBaseService;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downstorage.entity.DownStorageCage;
@@ -20,18 +19,21 @@
 */
public interface DownStorageCageService extends MPJBaseService<DownStorageCage> {
    DownGlassTask createDownGlassTask(GlassInfo glassInfo, String startCell, String endCell, String taskType);
    DownGlassTask createDownGlassTask(DownStorageCageDetails glassInfo, String startCell, String endCell, String taskType);
    DownGlassTask createDownGlassTask(GlassInfo glassInfo, Integer startCell, Integer endCell, String taskType);
    DownGlassTask createDownGlassTask(DownStorageCageDetails glassInfo, Integer startCell, Integer endCell, String taskType);
    //    List<Map<String, Object>> selectCacheLeisure();
    /**
     * @return 找到空格子
     */
    List<DownStorageCageDetails> selectCacheEmpty() ;
    DownStorageCage selectCacheEmpty(int currentSlot, boolean flag);
    /**
     * @return 找到空格子
     */
    List<DownStorageCageDetails> selectCacheEmpty();
    /**
     * @param downStorageCage
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/impl/DownStorageCageDetailsServiceImpl.java
@@ -3,12 +3,15 @@
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.github.yulichang.query.MPJLambdaQueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.common.config.Const;
import com.mes.downstorage.entity.DownStorageCage;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.downstorage.mapper.DownStorageCageDetailsMapper;
@@ -110,6 +113,7 @@
        return downStorageCageDetailsMapper.selectJoinMaps(JoinWrappers.lambda(DownStorageCageDetails.class) // 使用 JoinWrappers.lambda 创建联合查询
                .selectAll(DownStorageCageDetails.class) // 选择所有字段
                .eq(DownStorageCage::getSlot, DownStorageCageDetails::getSlot) // 设置关联条件
                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN)
                .orderByAsc(DownStorageCage::getSlot) // 按 slot 字段升序排序
        );
    }
@@ -160,38 +164,58 @@
//
//    }
  //  @Override
//    public List<GlassInfo>  DirectConnection(){
//        LambdaQueryWrapper<GlassInfo> queryWrapper2 = Wrappers.lambdaQuery();
//        queryWrapper2.select(GlassInfo::getFlowCardId,
//                GlassInfo::getGlassId,
//                GlassInfo::getTemperingLayoutId,
//                GlassInfo::getTemperingFeedSequence)
//                .notInSql(GlassInfo::getGlassId, "SELECT glass_id FROM down_glass_info")
//                .orderByAsc(GlassInfo::getTemperingLayoutId)
//                .orderByDesc(GlassInfo::getTemperingFeedSequence)
//                .last("LIMIT 1");
//
//        // 查询 GlassInfo 表
//        log.info("直通查询");
//        return glassInfoMapper.selectList(queryWrapper2);
//
//    };
    @Override
    public List<GlassInfo>  DirectConnection(){
        LambdaQueryWrapper<GlassInfo> queryWrapper2 = Wrappers.lambdaQuery();
        queryWrapper2.select(GlassInfo::getFlowCardId,
                GlassInfo::getGlassId,
                GlassInfo::getTemperingLayoutId,
                GlassInfo::getTemperingFeedSequence)
    public boolean DirectConnection(GlassInfo glassInfo) {
        LambdaQueryWrapper<GlassInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(GlassInfo::getGlassId, glassInfo.getGlassId())
                .notInSql(GlassInfo::getGlassId, "SELECT glass_id FROM down_glass_info")
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderByDesc(GlassInfo::getTemperingFeedSequence)
                .orderByDesc(GlassInfo::getGlassType)
                .groupBy(GlassInfo::getFlowCardId)
                .last("LIMIT 1");
        // 查询 GlassInfo 表
        log.info("直通查询");
        return glassInfoMapper.selectList(queryWrapper2);
        // 查询符合条件的 GlassInfo 记录数量
        int count = glassInfoMapper.selectCount(queryWrapper);
    };
        return count > 0;
    }
    @Override
    public DownStorageCageDetails getGlassInfoMaxCount() {
        return baseMapper.getGlassInfoMaxCount();
    }
    @Override
    public List<DownStorageCageDetails> CacheOut1(int start, int end) {
        List<DownStorageCageDetails> cageDetails = downStorageCageDetailsMapper.selectList(null);
        // 创建一个 LambdaQueryWrapper 实例
        LambdaQueryWrapper<DownStorageCageDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 条件 state=100
        lambdaQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
        List<DownStorageCageDetails> cageDetails = downStorageCageDetailsMapper.selectList(lambdaQueryWrapper);
        // Step 5: 判断 down_storage_cage_details 结果数量是否为9,如果是,则执行另外一个查询
        if (cageDetails.size() == 9) {
            log.info("1、笼子满了的时候,按照笼内版图id 版图片序出");
            List<DownWorkstation> workstationList = downWorkstationMapper.selectList(new QueryWrapper<DownWorkstation>().between("workstation_id", start, end));
            List<String> flowCardIds = new ArrayList<>();
            for (DownWorkstation workstation : workstationList) {
@@ -207,6 +231,7 @@
            anotherQueryWrapper.orderByAsc(DownStorageCageDetails::getTemperingLayoutId);
            anotherQueryWrapper.orderByDesc(DownStorageCageDetails::getTemperingFeedSequence);
            anotherQueryWrapper.in(DownStorageCageDetails::getFlowCardId, flowCardIds);
            anotherQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
            anotherQueryWrapper.last("LIMIT 1");
            return downStorageCageDetailsMapper.selectList(anotherQueryWrapper);
        } else {
@@ -214,12 +239,10 @@
            // Step 1: 查询 DownWorkstation 表获取对应 workstation_id 的 flow_card_id
            List<DownWorkstation> workstationList = downWorkstationMapper.selectList(new QueryWrapper<DownWorkstation>().between("workstation_id", start, end));
            List<String> flowCardIds = new ArrayList<>();
            for (DownWorkstation workstation : workstationList) {
                flowCardIds.add(workstation.getFlowCardId());
            }
            if (flowCardIds.isEmpty()) {
                log.error("2、未找到对应的 flow_card_id");
                return Collections.emptyList(); // 返回空列表或者抛出异常,视情况而定
@@ -246,7 +269,7 @@
            LambdaQueryWrapper<DownStorageCageDetails> cageDetailsQueryWrapper = Wrappers.lambdaQuery();
            cageDetailsQueryWrapper.in(DownStorageCageDetails::getGlassId, glassIds);
            cageDetailsQueryWrapper.in(DownStorageCageDetails::getFlowCardId, flowCardIds);
            cageDetailsQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
            log.info("按照流程卡的版图id 版图片序出");
            // Step 4: 查询 down_storage_cage_details 表并返回结果
            return downStorageCageDetailsMapper.selectList(cageDetailsQueryWrapper);
@@ -256,4 +279,98 @@
    }
        @Override
        public List<DownStorageCageDetails> CacheOut2(int start, int end) {
            // 创建一个 LambdaQueryWrapper 实例
            LambdaQueryWrapper<DownStorageCageDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 条件 state=100
            lambdaQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
            List<DownStorageCageDetails> cageDetails = downStorageCageDetailsMapper.selectList(lambdaQueryWrapper);
            // Step 5: 判断 down_storage_cage_details 结果数量是否为9,如果是,则执行另外一个查询
            if (cageDetails.size() == 9) {
                log.info("1、笼子满了的时候,按照笼内流程卡顺序出 GlassType目前是流程卡中的顺序");
                List<DownWorkstation> workstationList = downWorkstationMapper.selectList(new QueryWrapper<DownWorkstation>().between("workstation_id", start, end));
                List<String> flowCardIds = new ArrayList<>();
                for (DownWorkstation workstation : workstationList) {
                    flowCardIds.add(workstation.getFlowCardId());
                }
                if (flowCardIds.isEmpty()) {
                    log.error("未找到对应的 flow_card_id");
                    return Collections.emptyList(); // 返回空列表或者抛出异常,视情况而定
                }
                LambdaQueryWrapper<DownStorageCageDetails> anotherQueryWrapper = Wrappers.lambdaQuery();
                anotherQueryWrapper.orderByAsc(DownStorageCageDetails::getGlassType);
                anotherQueryWrapper.in(DownStorageCageDetails::getFlowCardId, flowCardIds);
                anotherQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
                anotherQueryWrapper.last("LIMIT 1");
                return downStorageCageDetailsMapper.selectList(anotherQueryWrapper);
            } else {
                // Step 1: 查询 DownWorkstation 表获取对应 workstation_id 的 flow_card_id
                List<DownWorkstation> workstationList = downWorkstationMapper.selectList(new QueryWrapper<DownWorkstation>().between("workstation_id", start, end));
                List<String> flowCardIds = new ArrayList<>();
                for (DownWorkstation workstation : workstationList) {
                    flowCardIds.add(workstation.getFlowCardId());
                }
                if (flowCardIds.isEmpty()) {
                    log.error("2、未找到对应的 flow_card_id");
                    return Collections.emptyList(); // 返回空列表或者抛出异常,视情况而定
                }
                log.info("流程卡:{}", flowCardIds);
                LambdaQueryWrapper<GlassInfo> queryWrapper2 = Wrappers.lambdaQuery();
                queryWrapper2.select(GlassInfo::getFlowCardId,
                        GlassInfo::getGlassId)
                        .notInSql(GlassInfo::getGlassId, "SELECT glass_id FROM down_glass_info")
                        .orderByAsc(GlassInfo::getGlassType)
                        .last("LIMIT 1");
                // 查询 GlassInfo 表
                List<GlassInfo> glassInfos = glassInfoMapper.selectList(queryWrapper2);
                if (glassInfos.isEmpty()) {
                    log.error("未找到对应的玻璃信息");
                    return Collections.emptyList(); // 返回空列表或者抛出异常,视情况而定
                }
                // Step 3: 构造查询 down_storage_cage_details 表的条件
                List<String> glassIds = glassInfos.stream().map(GlassInfo::getGlassId).collect(Collectors.toList());
                LambdaQueryWrapper<DownStorageCageDetails> cageDetailsQueryWrapper = Wrappers.lambdaQuery();
                cageDetailsQueryWrapper.in(DownStorageCageDetails::getGlassId, glassIds);
                cageDetailsQueryWrapper.in(DownStorageCageDetails::getFlowCardId, flowCardIds);
                cageDetailsQueryWrapper.eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN);
                log.info("按照流程卡的顺序出");
                // Step 4: 查询 down_storage_cage_details 表并返回结果
                return downStorageCageDetailsMapper.selectList(cageDetailsQueryWrapper);
            }
    }
    @Override
    public boolean identWorn(String glassId, int ControlsId) {
        List<DownStorageCageDetails> edgStorageCageDetails = baseMapper.selectList(new MPJLambdaQueryWrapper<DownStorageCageDetails>().selectAll(DownStorageCageDetails.class).eq(DownStorageCageDetails::getGlassId, glassId));
        if (edgStorageCageDetails.size() == 1) {
            DownStorageCageDetails item = edgStorageCageDetails.get(0);
            item.setState(ControlsId);
            baseMapper.update(item, new MPJLambdaWrapper<DownStorageCageDetails>().selectAll(DownStorageCageDetails.class).eq(DownStorageCageDetails::getGlassId, glassId));
            return true;
        }
        return false;
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downstorage/service/impl/DownStorageCageServiceImpl.java
@@ -1,15 +1,13 @@
package com.mes.downstorage.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
//import com.mes.device.PlcParameterObject;
import com.mes.common.config.Const;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.downstorage.entity.DownStorageCage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.downstorage.mapper.DownStorageCageDetailsMapper;
import com.mes.downstorage.mapper.DownStorageCageMapper;
@@ -17,7 +15,6 @@
import com.mes.downstorage.service.DownStorageCageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.pp.entity.OptimizeDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,7 +48,7 @@
    private DownStorageCageDetailsMapper downStorageCageDetailsMapper;
    @Override
    public DownGlassTask createDownGlassTask(GlassInfo glassInfo, String startCell, String endCell, String taskType) {
    public DownGlassTask createDownGlassTask(GlassInfo glassInfo, Integer startCell, Integer endCell, String taskType) {
        DownGlassTask downGlassTask = new DownGlassTask();
        BeanUtils.copyProperties(glassInfo, downGlassTask);
@@ -63,7 +60,7 @@
    }
    @Override
    public DownGlassTask createDownGlassTask(DownStorageCageDetails glassInfo, String startCell, String endCell, String taskType) {
    public DownGlassTask createDownGlassTask(DownStorageCageDetails glassInfo, Integer startCell, Integer endCell, String taskType) {
        DownGlassTask downGlassTask = new DownGlassTask();
        BeanUtils.copyProperties(glassInfo, downGlassTask);
@@ -72,27 +69,61 @@
        downGlassTask.setEndCell(endCell);
        return downGlassTask;
    }
    //找到空格子
    @Override
    public List<DownStorageCageDetails> selectCacheEmpty() {
        return baseMapper.selectJoinList(DownStorageCageDetails.class,
        return this.selectJoinList(DownStorageCageDetails.class,
                JoinWrappers.lambda(DownStorageCage.class)
                        .selectAll(DownStorageCage.class)
                        .select(DownStorageCageDetails::getWidth, DownStorageCageDetails::getHeight, DownStorageCageDetails::getGlassId)
                        .leftJoin(DownStorageCageDetails.class, on -> on
                                .eq(DownStorageCageDetails::getDeviceId, DownStorageCage::getDeviceId)
                                .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot))
                                .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot)
                                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN))
                        .isNull(DownStorageCageDetails::getSlot)
        );
    }
    //找到空格子
    @Override
    public DownStorageCage selectCacheEmpty(int currentSlot, boolean flag) {
        List<DownStorageCage> emptyList = this.selectJoinList(DownStorageCage.class,
                JoinWrappers.lambda(DownStorageCage.class)
                        .selectAll(DownStorageCage.class)
                        .leftJoin(DownStorageCageDetails.class, on -> on
                                .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot)
                                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN))
                        .isNull(DownStorageCageDetails::getSlot)
                        .last("order by abs(t.slot - " + currentSlot + ")  asc limit 2")
        );
        if (flag && CollectionUtil.isNotEmpty(emptyList)) {
            return emptyList.get(0);
        }
        if (CollectionUtil.isEmpty(emptyList) || emptyList.size() == 1) {
            return null;
        }
        return emptyList.get(0);
    }
    @Override
    public List<DownStorageCageDetails> selectCacheMax() {
        return baseMapper.selectJoinList(DownStorageCageDetails.class,
                JoinWrappers.lambda(DownStorageCage.class)
                        // 添加 DownStorageCage 的 enableState 为 1 的条件
                        .select(DownStorageCageDetails::getFlowCardId)
                        .leftJoin(DownStorageCageDetails.class, on -> on
                                .eq(DownStorageCageDetails::getDeviceId, DownStorageCage::getDeviceId)
                                .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot)
                                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN))
                        .isNull(DownStorageCageDetails::getSlot)
                        .eq(DownStorageCage::getEnableState, 1)
                        .groupBy(DownStorageCageDetails::getFlowCardId) // 根据 flowCardId 分组
                        // 使用子查询和排序来获取相同 FlowCardId 中的最多记录
                        .having("count(*) = (select max(cnt) from (select count(*) as cnt from down_storage_cage_details group by flow_card_id) as temp)")
        );
    }
    @Override
@@ -103,7 +134,8 @@
                .select(DownStorageCageDetails::getGlassId, DownStorageCageDetails::getWidth, DownStorageCageDetails::getHeight, DownStorageCageDetails::getId)
                .leftJoin(DownStorageCageDetails.class, on -> on
                        .eq(DownStorageCageDetails::getDeviceId, DownStorageCage::getDeviceId)
                        .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot))
                        .eq(DownStorageCageDetails::getSlot, DownStorageCage::getSlot)
                        .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN))
        );
    }
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstation.java
@@ -53,6 +53,11 @@
     */
    private Integer workState;
    /**
     * 层数
     */
    private Integer layer;
    /**
     * 总数量
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstationTask.java
@@ -29,12 +29,12 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private double height;
    /**
     * 膜系
@@ -44,7 +44,7 @@
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    /**
     * 流程卡号
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/DownWorkstionAndDownGlassinfo.java
@@ -6,8 +6,6 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
@@ -70,19 +68,19 @@
    /**
     * 宽
     */
    private Double width;
    private double width;
    /**
     * 高
     */
    private Double height;
    private Double totalwidth;
    private double height;
    private double totalwidth;
    private Double totalheight;
    private double totalheight;
    /**
     * 厚度
     */
    private Double thickness;
    private double thickness;
    private String Filmsid;
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/downworkstation/entity/dto/DownGlassInfoDTO.java
New file
@@ -0,0 +1,32 @@
package com.mes.downworkstation.entity.dto;
import com.mes.glassinfo.entity.GlassInfo;
import lombok.Data;
import java.util.List;
/**
 * @Author : zhoush
 * @Date: 2024/6/21 16:06
 * @Description:
 */
@Data
public class DownGlassInfoDTO {
    /**
     * 流程卡号
     */
    private String flowCardId;
    /**
     * 层数
     */
    private Integer layer;
    /**
     * 落架数量
     */
    private Integer count;
    /**
     * 流程卡未进片的玻璃信息
     */
    private List<GlassInfo> glassInfoList;
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownCacheGlassTask.java
@@ -1,6 +1,7 @@
package com.mes.job;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.common.config.Const;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downglassinfo.service.DownGlassInfoService;
@@ -41,38 +42,58 @@
    @Autowired
    DownWorkstationService downWorkstationService;
    @Autowired
     DownGlassInfoService downGlassInfoService;
    DownGlassInfoService downGlassInfoService;
    @Autowired
    private DownWorkstationTaskService downWorkstationTaskService;
//    @Value("${mes.threshold}")
    //    @Value("${mes.threshold}")
    private int threshold;
  // @Scheduled(fixedDelay = 1000)
//    @Scheduled(fixedDelay = 1000)
    public void autoBindRack() {
        log.info("根据缓存中已经进片的玻璃种数量最多的流程卡号自动绑定一个启用状态的空架子");
        List<DownStorageCageDetails> Details = downStorageCageService.selectCacheMax();
        if (Details.size() > 0) {
            DownStorageCageDetails downStorageCageDetails = Details.get(0);
            String flowCardId = downStorageCageDetails.getFlowCardId();
            int glassInfoCount = glassInfoService.getGlassInfoCountByFlowCardId(flowCardId);
            DownWorkstation downWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>().eq(DownWorkstation::getFlowCardId, null));
            List<DownWorkstation> downWorkstations = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
                    .eq(DownWorkstation::getEnableState, 1));
            if (!downWorkstations.stream().anyMatch(workstation -> workstation.getFlowCardId().equals(flowCardId))) {
                downWorkstationService.updateFlowCardIdAndCount(flowCardId, glassInfoCount, downWorkstation.getWorkstationId());
            }
        }
    }
    // @Scheduled(fixedDelay = 1000)
    public void plcdownGlassTask() {
   //   PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        //   PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
//        String glassIdeValue = plcParameterObject.getPlcParameter("A05_scanning_ID").getValue();
//        String confirmationWrodValue = plcParameterObject.getPlcParameter("MES_confirmation_word").getValue();
//        String outGlassstate = plcParameterObject.getPlcParameter("A09_glass_status").getValue();
//        String confirmationWrodAddress = plcParameterObject.getPlcParameter("MES_confirmation_word").getAddress();
      // String G06RobotTaskRequestWord = plcParameterObject.getPlcParameter("G06RobotTaskRequestWord").getAddress();
//        String MESSendingWord = plcParameterObject.getPlcParameter("MES_confirmation_word").getAddress();
        // String G06RobotTaskRequestWord = plcParameterObject.getPlcParameter("G06RobotTaskRequestWord").getAddress();
                String taskRequestTypeValue ="0";
        String glassIdeValue ="NG24041101C002-2-6-1-6";
        String confirmationWrodValue ="1";
        String outGlassstate="1";
        String confirmationWrodAddress="1";
        String G11RobotTaskRequestWord ="0";
        String G06RobotTaskRequestWord ="0";
        String G13RobotTaskRequestWord ="0";
        String taskRequestTypeValue = "0";
        String glassIdeValue = "NG24041101C002-2-6-1-6";
        String confirmationWrodValue = "1";
        String outGlassstate = "1";
        String MESSendingWord = "1";
        String G11RobotTaskRequestWord = "0";
        String G06RobotTaskRequestWord = "0";
        String G13RobotTaskRequestWord = "0";
                log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态为:{}",
        log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态为:{}",
                taskRequestTypeValue, glassIdeValue, confirmationWrodValue, outGlassstate);
//        if ("0".equals(taskRequestTypeValue)) {
@@ -81,52 +102,48 @@
//                return;
//            }
//            log.info("2、获取到的请求字为0,将确认字改为0");
//            S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 0);
//            S7object.getinstance().plccontrol.WriteWord(MESSendingWord, 0);
//            return;
//        }
//        if (!"0".equals(confirmationWrodValue)) {
//            log.info("2、获取到的请求字不为0,将确认字改为0");
//            S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 0);
//            S7object.getinstance().plccontrol.WriteWord(MESSendingWord, 0);
//            return;
//        }
        if ("1".equals(taskRequestTypeValue)) {
            log.info("3、进片请求,且确认字为0,执行进片任务");
            inTo(glassIdeValue, confirmationWrodAddress);
            inTo(glassIdeValue, MESSendingWord);
        } else if ("2".equals(taskRequestTypeValue)) {
            log.info("3、出片请求,且确认字为0,执行进片任务");
            outTo( confirmationWrodAddress);
            outTo(MESSendingWord);
        } else if ("3".equals(taskRequestTypeValue)) {
            log.info("3、进片和出片都空闲,执行出片任务");
            if (outTo(confirmationWrodAddress)) {
                inTo(glassIdeValue, confirmationWrodAddress);
            if (outTo(MESSendingWord)) {
                inTo(glassIdeValue, MESSendingWord);
            }
        }
        if (("1".equals(G11RobotTaskRequestWord) || "1".equals(G06RobotTaskRequestWord))  || "1".equals(G13RobotTaskRequestWord)) {
            log.info("4、有机器人下片请求,执行下片任务");
        if (("0".equals(G11RobotTaskRequestWord) || "0".equals(G06RobotTaskRequestWord)) || "0".equals(G13RobotTaskRequestWord)) {
            log.info("4、有下片完成信号更新落架数量");
            insertdownglassinfo();
        }
        //自动绑定架子,如果工位表没有绑定架子,默认将笼子中数量最多的流程卡号绑定机器手2的空架子
    }
    /**
     * 进片任务
     *
     * @param glassId
     * @param confirmationWrodAddress
     * @param MESSendingWord
     * @param
     */
    private void inTo(String glassId, String confirmationWrodAddress) {
    private void inTo(String glassId, String MESSendingWord) {
        log.info("1、按照玻璃id:{}获取玻璃小片信息", glassId);
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        if (glassInfo == null) {
@@ -135,152 +152,152 @@
        }
        log.info("2、获取到的玻璃信息为{}", glassInfo);
        if (glassInfo.getGlassId().equals(downStorageCageDetailsService.DirectConnection()) ) {
        if (downStorageCageDetailsService.DirectConnection(glassInfo)) {
            //直通
            log.info("3、如果当前玻璃属于版图id和片序的顺序则直通,执行下片任务");
            //log.info("3、如果当前玻璃属于版图id和片序的顺序则直通,执行下片任务");
            log.info("3、如果当前玻璃属于流程卡中的片序的顺序则直通,执行下片任务");
            DownWorkstation downWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>().eq(DownWorkstation::getFlowCardId, glassInfo.getFlowCardId()));
            int WorkstationId=downWorkstation.getWorkstationId();
            DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(glassInfo, "0", String.valueOf(WorkstationId), "3");
            int WorkstationId = downWorkstation.getWorkstationId();
            DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(glassInfo, 0, WorkstationId, "3");
            downGlassTaskService.insertCacheTask(downGlassTask);
        }else{
        } else {
            log.info("4、如果不属于版图id和片序的顺序执行进片任务");
        //添加进片任务  查找空格
        List<DownStorageCageDetails> list = downStorageCageService.selectCacheEmpty();
        if(list.size()>0){
            DownStorageCageDetails item = list.get(0);
            // log.info("4、如果不属于版图id和片序的顺序执行进片任务");
            log.info("4、如果不属于流程卡中的片序的顺序执行进片任务");
            //添加进片任务  查找空格
            List<DownStorageCageDetails> list = downStorageCageService.selectCacheEmpty();
            if (list.size() > 0) {
                DownStorageCageDetails item = list.get(0);
                log.info("5、查询卧式理片笼里面的空格:{}", list);
                log.info("6、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
                DownStorageCageDetails details = new DownStorageCageDetails();
                BeanUtils.copyProperties(glassInfo, details);
                details.setState(Const.GLASS_STATE_IN);
                details.setGlassId(glassInfo.getGlassId());
                details.setSlot(item.getSlot());
                details.setDeviceId(item.getDeviceId());
                downStorageCageDetailsService.save(details);
                log.info("7、玻璃信息已存入理片笼详情表,玻璃信息为{}", details);
        log.info("5、查询卧式理片笼里面的空格:{}", list);
        log.info("6、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
        DownStorageCageDetails details = new DownStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, details);
        details.setState(1);
        details.setGlassId(glassInfo.getGlassId());
        details.setSlot(item.getSlot());
        details.setDeviceId(item.getDeviceId());
        downStorageCageDetailsService.save(details);
        log.info("7、玻璃信息已存入理片笼详情表,玻璃信息为{}", details);
            DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(glassInfo, "0", item.getSlot() + "", "1");
        //添加进片任务
        log.info("8、生成进片任务信息存入任务表{}", downGlassTask);
            downGlassTaskService.insertCacheTask(downGlassTask);
        }
                DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(glassInfo, 0, item.getSlot(), "1");
                //添加进片任务
                log.info("8、生成进片任务信息存入任务表{}", downGlassTask);
                downGlassTaskService.insertCacheTask(downGlassTask);
            }
        }
        log.info("9、发送确认字完成");
        //S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 1);
        //S7object.getinstance().plccontrol.WriteWord(MESSendingWord, 1);
    }
    /**
     * 出片任务
     *
     * @param confirmationWrodAddress
     *
     * @param MESSendingWord
     */
    private Boolean outTo( String confirmationWrodAddress) {
        log.info("单片情况根据传入的料架号 查询符合按照版图id和片序出片,并且优先出满架的小片");
        List<DownStorageCageDetails> list = downStorageCageDetailsService.CacheOut1(1,3);
    private Boolean outTo(String MESSendingWord) {
        // log.info("单片情况根据传入的料架号 查询符合按照版图id和片序出片,并且优先出满架的小片");
        log.info("单片情况根据传入的料架号 查询符合按照流程卡中顺序出片,并且优先出满架的小片");
        List<DownStorageCageDetails> list2 = downStorageCageDetailsService.CacheOut1(4,6);
//        List<DownStorageCageDetails> list1to3 = downStorageCageDetailsService.CacheOut1(1, 3);
//        List<DownStorageCageDetails> list4to6 = downStorageCageDetailsService.CacheOut1(4, 6);
        List<DownStorageCageDetails> list1to6 = downStorageCageDetailsService.CacheOut2(1, 6);
        List<DownStorageCageDetails> list3 = downStorageCageDetailsService.CacheOut1(1,6);
        DownStorageCageDetails selectedItem = null;
        Integer endCell = null;
        // 优先 超出尺寸优先人工出片 人工处理
        if (!list3.isEmpty()) {
            DownStorageCageDetails item3 = list3.get(0);
        if (!list1to6.isEmpty()) {
            DownStorageCageDetails item3 = list1to6.get(0);
            //后期有生产规则
            if (item3.getHeight() >= 2500 && item3.getWidth() >= 2660) {
                log.info("人工处理");
                String endcell = "7";
                selectedItem = item3;
                DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(item3, "9", endcell, "2");
                downGlassTaskService.insertCacheTask(downGlassTask);
              // S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 2);
              return true;
            }
            else if (!list2.isEmpty() && !list3.isEmpty()) {
                log.info("前后端都空闲 优先后端出片并且优先满架");
                DownStorageCageDetails item4 = list2.get(0);
                DownWorkstation downWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>().eq(DownWorkstation::getFlowCardId, item4.getFlowCardId()));
                String endcell = String.valueOf(downWorkstation.getWorkstationId());
                DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(item4, "9", endcell, "2");
                downGlassTaskService.insertCacheTask(downGlassTask);
                //S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 2);
                return true;
            }
            // 按照版图id和片序符合前端出片
            else if (!list.isEmpty()) {
                log.info("前端出片");
                DownStorageCageDetails item = list.get(0);
                DownWorkstation downWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>().eq(DownWorkstation::getFlowCardId, item.getFlowCardId()));
                String endcell = String.valueOf(downWorkstation.getWorkstationId());
                // 出到 G06
                DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(item, "9", endcell, "2");
                downGlassTaskService.insertCacheTask(downGlassTask);
                // S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 2);
                return true;
                // 按照版图id和片序符合后端出片
            } else if (!list2.isEmpty()) {
                log.info("后端出片");
                DownStorageCageDetails item2 = list2.get(0);
                DownWorkstation downWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>().eq(DownWorkstation::getFlowCardId, item2.getFlowCardId()));
                String endcell = String.valueOf(downWorkstation.getWorkstationId());
                // 出到 G11
                DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(item2, "9", endcell, "2");
                downGlassTaskService.insertCacheTask(downGlassTask);
                //  S7object.getinstance().plccontrol.WriteWord(confirmationWrodAddress, (short) 2);
                return true;
            } else if (!!list1to6.isEmpty()) {
                log.info("前后端都空闲优先满架");
                selectedItem = list1to6.get(0);
            }
        }
        //如果同时前后端都空闲 优先后端出片并且优先满架
        // 按照版图id和片序符合前端出片
//        if (selectedItem == null && !list1to3.isEmpty()) {
//            log.info("前端出片");
//            selectedItem = list1to3.get(0);
//        }
//
//        // 按照版图id和片序符合后端出片
//        if (selectedItem == null && !list4to6.isEmpty()) {
//            log.info("后端出片");
//            selectedItem = list4to6.get(0);
//        }
        if (selectedItem != null) {
            DownWorkstation downWorkstation = downWorkstationService.getOne(
                    new LambdaQueryWrapper<DownWorkstation>()
                            .eq(DownWorkstation::getFlowCardId, selectedItem.getFlowCardId())
            );
            endCell = downWorkstation.getWorkstationId();
            if (endCell == null) {
                endCell = 7;
            }
            DownGlassTask downGlassTask = downStorageCageService.createDownGlassTask(selectedItem, 9, endCell, "2");
            downGlassTaskService.insertCacheTask(downGlassTask);
            LambdaQueryWrapper<DownStorageCageDetails> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DownStorageCageDetails::getGlassId, selectedItem.getGlassId());
            DownStorageCageDetails updateDetail = new DownStorageCageDetails();
            updateDetail.setState(Const.GLASS_STATE_OUT);
            downStorageCageDetailsService.update(updateDetail, wrapper);
            log.info("更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
            // S7object.getinstance().plccontrol.WriteWord(MESSendingWord, 2);
            return true;
        }
        // 返回结果
        return false;
    }
//
    //
    public void insertdownglassinfo() {
        try {
        List<DownGlassTask> taskdownGlassInf = downGlassTaskService.getUnloadingTaskState();
        if (taskdownGlassInf != null && !taskdownGlassInf.isEmpty()) {
            List<DownGlassTask> taskdownGlassInf = downGlassTaskService.getUnloadingTaskState();
            if (taskdownGlassInf != null && !taskdownGlassInf.isEmpty()) {
            for (DownGlassTask downGlassInfo : taskdownGlassInf) {
                // 创建新的 DownGlassInfo 对象并设置相关属性
                DownGlassInfo newdownGlassInfo = new DownGlassInfo();
                for (DownGlassTask downGlassInfo : taskdownGlassInf) {
                    // 创建新的 DownGlassInfo 对象并设置相关属性
                    DownGlassInfo newdownGlassInfo = new DownGlassInfo();
                Integer maxSequence = downGlassInfoService.getMaxSequenceByFlowCardId(downGlassInfo.getFlowCardId());
                // 初始化顺序字段值
                int sequence = maxSequence != null ? maxSequence + 1 : 1;
                BeanUtils.copyProperties(downGlassInfo, newdownGlassInfo);
                // 设置顺序字段值
                newdownGlassInfo.setSequence(sequence);
                // 插入数据到下片玻璃信息表
                downGlassInfoService.insertDownGlassInfo(newdownGlassInfo);
                log.info("插入数据到下片玻璃信息表");
                DownWorkstation downWorkstation1 = downWorkstationService.selectByFlowCardId(downGlassInfo.getFlowCardId());
                downWorkstationService.updateracksnumber(downGlassInfo.getFlowCardId(), downWorkstation1.getRacksnumber() + 1);
                log.info("更新落架数量");
                sequence++; // 递增顺序字段值
                    Integer maxSequence = downGlassInfoService.getMaxSequenceByFlowCardId(downGlassInfo.getFlowCardId(), downGlassInfo.getLayer());
                    // 初始化顺序字段值
                    int sequence = maxSequence != null ? maxSequence + 1 : 1;
                    BeanUtils.copyProperties(downGlassInfo, newdownGlassInfo);
                    // 设置顺序字段值
                    newdownGlassInfo.setSequence(sequence);
                    // 插入数据到下片玻璃信息表
                    downGlassInfoService.insertDownGlassInfo(newdownGlassInfo);
                    log.info("插入数据到下片玻璃信息表");
                    DownWorkstation downWorkstation1 = downWorkstationService.selectByFlowCardId(downGlassInfo.getFlowCardId());
                    downWorkstationService.updateracksnumber(downGlassInfo.getFlowCardId(), downWorkstation1.getRacksnumber() + 1);
                    log.info("更新落架数量");
//                    LambdaQueryWrapper<DownGlassTask> wrapper = new LambdaQueryWrapper<>();
//                    wrapper.eq(DownGlassTask::getGlassId, newdownGlassInfo.getGlassId());
//                    DownGlassTask updateDetail = new DownGlassTask();
//                    updateDetail.setTaskStauts(2);
//                    downGlassTaskService.update(updateDetail, wrapper);
                    sequence++; // 递增顺序字段值
                }
            }
        }
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownLoadCacheGlassTask.java
New file
@@ -0,0 +1,520 @@
package com.mes.job;
import cn.hutool.core.lang.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.device.PlcParameterObject;
import com.mes.downglassinfo.entity.DownGlassInfo;
import com.mes.downglassinfo.entity.DownGlassTask;
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.downstorage.entity.DownStorageCage;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.downstorage.service.DownStorageCageDetailsService;
import com.mes.downstorage.service.DownStorageCageService;
import com.mes.downworkstation.entity.DownWorkstation;
import com.mes.downworkstation.entity.dto.DownGlassInfoDTO;
import com.mes.downworkstation.service.DownWorkstationService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.tools.S7control;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
 * @Date: 2024/5/8 8:17
 * @Description:
 */
@Component
@Slf4j
public class DownLoadCacheGlassTask {
    @Autowired
    DownGlassTaskService downGlassTaskService;
    @Autowired
    GlassInfoService glassInfoService;
    @Autowired
    DownStorageCageDetailsService downStorageCageDetailsService;
    @Autowired
    DownStorageCageService downStorageCageService;
    @Autowired
    DownWorkstationService downWorkstationService;
    @Autowired
    DownGlassInfoService downGlassInfoService;
    @Value("${mes.threshold}")
    private Integer threshold;
    @Value("${mes.throughWidth}")
    private Integer throughWidth;
    @Value("${mes.throughHeight}")
    private Integer throughHeight;
    @Value("${mes.maxWidth}")
    private Integer maxWidth;
    @Value("${mes.maxHeight}")
    private Integer maxHeight;
    @Scheduled(fixedDelay = 1000)
    public void plcHomeEdgTask() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String requestWord = plcParameterObject.getPlcParameter("requestWord").getValue();
        String glassIdeValue = plcParameterObject.getPlcParameter("requestID").getValue();
        //A08  A09表示线路相同  可做等价  无数据转int异常
        String out06Glassstate = plcParameterObject.getPlcParameter("glassStatus06").getValue();
        String out08Glassstate = plcParameterObject.getPlcParameter("glassStatus08").getValue();
        String out11Glassstate = plcParameterObject.getPlcParameter("glassStatus11").getValue();
        String out13Glassstate = plcParameterObject.getPlcParameter("glassStatus13").getValue();
        String confirmationWrodValue = plcParameterObject.getPlcParameter("confirmationWord").getValue();
        String confirmationWrodAddress = plcParameterObject.getPlcParameter("confirmationWord").getAddress();
        String currentSlot = plcParameterObject.getPlcParameter("currentCell").getValue();
        log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态分别为:g06:{}、g08:{}、g11:{}、g13:{},当前格子号为:{}",
                requestWord, glassIdeValue, confirmationWrodValue, out06Glassstate, out08Glassstate, out11Glassstate, out13Glassstate, currentSlot);
        if ("0".equals(requestWord)) {
            if ("0".equals(confirmationWrodValue)) {
                log.info("2、获取到的请求字为0,且确认字为0,不执行任务");
                return;
            }
            log.info("2、获取到的请求字为0,将确认字改为0");
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 0);
            return;
        }
        if (!"0".equals(confirmationWrodValue)) {
            log.info("2、获取到的请求字不为0,将确认字不为0,直接结束");
            return;
        }
        if ("1".equals(requestWord)) {
            log.info("2、进片请求,且确认字为0,执行进片任务");
            inTo(glassIdeValue, requestWord, currentSlot);
        } else if ("2".equals(requestWord)) {
            //09空闲 :1      10空闲 :2        都空闲:3    其他0
            log.info("2、出片请求,且确认字为0,执行进片任务");
            outTo(out06Glassstate, out08Glassstate, out11Glassstate, out13Glassstate, glassIdeValue, currentSlot);
        } else if ("3".equals(requestWord)) {
            log.info("2、进片和出片都空闲,执行出片任务");
            //加笼子里面是否有玻璃,有先出,无玻璃先进
            boolean outFlase = outTo(out06Glassstate, out08Glassstate, out11Glassstate, out13Glassstate, glassIdeValue, currentSlot);
            log.info("出片任务是否完成:{},失败且玻璃id:{}不为空则执行进片任务", outFlase, glassIdeValue);
            if (!outFlase && StringUtils.isNotBlank(glassIdeValue)) {
                inTo(glassIdeValue, requestWord, currentSlot);
            }
        }
    }
    public void inTo(String glassId, String requestWord, String currentSlot) {
        log.info("1、按照玻璃id:{}获取玻璃小片信息,当前格子为:{}", glassId, currentSlot);
        //添加进片任务  查找空格
        DownStorageCage nearestEmpty = downStorageCageService.selectCacheEmpty(Integer.parseInt(currentSlot), Boolean.FALSE);
        Assert.isTrue(null != nearestEmpty, "格子已满,无法执行进片操作");
        log.info("2、查询卧式理片笼里面的空格:{}", nearestEmpty);
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");
        if ("1".equals(requestWord) && (glassInfo.getWidth() > throughWidth || glassInfo.getHeight() > throughHeight)) {
            log.info("玻璃当前尺寸宽:{},高:{}只能直通,当前进片任务需等待", glassInfo.getWidth(), glassInfo.getHeight());
            return;
        }
        Boolean checkFlag = Boolean.FALSE;
        //玻璃尺寸是否走人工下片
        if (glassInfo.getWidth() > maxWidth || glassInfo.getHeight() > maxHeight) {
            log.info("该玻璃尺寸走人工下片,直接进片");
        } else {
            log.info("该玻璃尺寸非人工下片");
            //获取该玻璃的流程卡是否已绑定架子
            DownWorkstation one = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>()
                    .eq(DownWorkstation::getLayer, glassInfo.getLayer())
                    .eq(DownWorkstation::getFlowCardId, glassInfo.getFlowCardId()));
            Boolean isBind = Boolean.FALSE;
            if (null != one) {
                log.info("该流程卡已绑定架子");
                isBind = Boolean.TRUE;
                checkFlag = multilayerCheck(glassInfo, isBind);
            }
            if (!checkFlag && !isBind) {
                log.info("该玻璃的流程卡未绑定架子,获取是否有空架子");
                List<DownWorkstation> list = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
                        .isNull(DownWorkstation::getFlowCardId));
                if (CollectionUtils.isNotEmpty(list)) {
                    log.info("有空架子,将流程卡与架子好绑定,执行进片任务 结束");
                    //绑定流程卡
                    downWorkstationService.update(new LambdaUpdateWrapper<DownWorkstation>()
                            .set(DownWorkstation::getFlowCardId, glassInfo.getFlowCardId())
                            .set(DownWorkstation::getLayer, glassInfo.getLayer())
                            .eq(DownWorkstation::getWorkstationId, list.get(0).getWorkstationId()));
                    checkFlag = Boolean.TRUE;
                }
            }
            if (!checkFlag) {
                log.info("无空架子,获取已绑定架子的流程卡信息,查看玻璃信息是否可被对调");
                List<DownGlassInfoDTO> downGlassInfoDTOList = downGlassInfoService.queryWorkStationIsIn(Boolean.FALSE);
                log.info("获取架子上已绑定流程卡落架的数量及未落架的玻璃数据:{}", downGlassInfoDTOList);
                if (CollectionUtils.isEmpty(downGlassInfoDTOList)) {
                    log.info("已绑定流程卡均无未落架玻璃,请及时处理架子上的玻璃,清除流程卡,执行进片任务");
                } else {
                    //替换玻璃信息
                    endLoop:
                    for (DownGlassInfoDTO e : downGlassInfoDTOList) {
                        List<GlassInfo> glassInfoList = e.getGlassInfoList();
                        for (GlassInfo item : glassInfoList) {
                            if (item.getWidth() == glassInfo.getWidth() && item.getHeight() == glassInfo.getHeight()
                                    && item.getThickness() == glassInfo.getThickness() && item.getFilmsid().equals(glassInfo.getFilmsid())) {
                                //玻璃是否为多层
                                checkFlag = multilayerCheck(item, Boolean.FALSE);
                                if (checkFlag) {
                                    //玻璃替换 仅替换流程卡id及层数
                                    String tempFlowCardId = item.getFlowCardId();
                                    Integer tempLayer = item.getLayer();
                                    String flowCardId = glassInfo.getFlowCardId();
                                    Integer layer = glassInfo.getLayer();
                                    log.info("替换流程卡信息,当前玻璃信息:{}的流程卡号{}及层数{},替换后玻璃信息:{}的流程卡号{}及层数{}",
                                            item, glassInfo, flowCardId, layer, tempFlowCardId, tempLayer);
                                    glassInfo.setFlowCardId(tempFlowCardId);
                                    glassInfo.setLayer(tempLayer);
                                    glassInfoService.updateById(glassInfo);
                                    item.setFlowCardId(flowCardId);
                                    item.setLayer(layer);
                                    glassInfoService.updateById(item);
                                    break endLoop;
                                }
                            }
                        }
                    }
                }
            }
        }
        //将任务插入理片笼详情表
        DownStorageCageDetails downStorageCageDetails = new DownStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, downStorageCageDetails);
        downStorageCageDetails.setState(Const.GLASS_STATE_IN);
        downStorageCageDetails.setSlot(nearestEmpty.getSlot());
        downStorageCageDetailsService.save(downStorageCageDetails);
//        生成进片任务
        initDownGlassTask(glassInfo, 0, nearestEmpty.getSlot(), Const.GLASS_CACHE_TYPE_IN);
    }
    public Boolean outTo(String glassStatus06, String out08Glassstate, String glassStatus11, String glassStatus13, String glassId, String currentSlot) {
        if ("2".equals(glassStatus06) && "2".equals(glassStatus11) && "2".equals(glassStatus13)) {
            log.info("G06、G11、G13分别为{},{}、{}非自动状态,无法出片", glassStatus06, glassStatus11, glassStatus13);
            return Boolean.FALSE;
        }
        List<DownStorageCageDetails> tempList = downStorageCageDetailsService.list(new LambdaQueryWrapper<DownStorageCageDetails>()
                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN));
        //获取待进片玻璃
        DownStorageCageDetails cageDetails = new DownStorageCageDetails();
        if (StringUtils.isNotBlank(glassId)) {
            GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
            BeanUtils.copyProperties(glassInfo, cageDetails);
            //获取当前笼子空格信息
            DownStorageCage empty = downStorageCageService.selectCacheEmpty(Integer.parseInt(currentSlot), Boolean.TRUE);
            cageDetails.setSlot(empty.getSlot());
            tempList.add(cageDetails);
        }
        log.info("笼内玻璃的数据有:{}", tempList);
        if (CollectionUtils.isEmpty(tempList)) {
            log.info("笼内没有玻璃,无法执行出片");
            return Boolean.FALSE;
        }
        Boolean flag08 = "1".equals(out08Glassstate) ? Boolean.TRUE : Boolean.FALSE;
        if (!generateTaskByShelf(glassStatus11, flag08, glassStatus13, tempList, cageDetails)) {
            return generateTaskByShelf(glassStatus11, !flag08, glassStatus13, tempList, cageDetails);
        }
        return Boolean.TRUE;
    }
    private Boolean multilayerCheck(GlassInfo glassInfo, boolean isBind) {
        //查询该流程卡是否为多层
        if (glassInfo.getTotalLayer() > 1) {
            log.info("按照流程卡获取当前流程卡各层已落架数量");
            DownGlassInfoDTO downGlassInfoDTO = downGlassInfoService.queryDownGlassMaxLayer(glassInfo.getFlowCardId());
            if (null == downGlassInfoDTO) {
                if (isBind) {
                    return Boolean.TRUE;
                } else {
                    log.info("架子已经占满,多层玻璃无法找到对应的格子,需执行替换玻璃的操作");
                    return Boolean.FALSE;
                }
            }
            if (downGlassInfoDTO.getLayer().equals(glassInfo.getLayer())) {
                log.info("当前玻璃的流程在架子上落架最多 直接进片");
                return Boolean.TRUE;
            }
            Integer sequence = downGlassInfoService.queryMaxSequence(glassInfo.getFlowCardId(), glassInfo.getLayer());
            log.info("获取当前玻璃需要放的次序:笼内同流程 同层数的通达次序+1:{}", sequence);
            DownGlassInfo downGlassInfo = downGlassInfoService.getOne(new LambdaQueryWrapper<DownGlassInfo>()
                    .eq(DownGlassInfo::getFlowCardId, downGlassInfoDTO.getFlowCardId())
                    .eq(DownGlassInfo::getLayer, downGlassInfoDTO.getLayer()).eq(DownGlassInfo::getSequence, sequence));
            log.info("拿当前版序获取玻璃信息{},按照次序判断当前玻璃是否尺寸对应的上(与数量最多的次序比较)。", downGlassInfo);
            if (null != downGlassInfoDTO && downGlassInfo.getWidth() == glassInfo.getWidth() && downGlassInfo.getHeight() == glassInfo.getHeight()) {
                log.info("相同次序玻璃对应上,可执行进片任务");
                return Boolean.TRUE;
            } else {
                log.info("同次序玻璃对应不上,需执行替换玻璃的操作");
                return Boolean.FALSE;
            }
        } else {
            log.info("非多层玻璃,直接进片");
            return Boolean.TRUE;
        }
    }
    private Boolean generateTaskByShelf(String glassStatus, Boolean flag08, String glassStatus13, List<DownStorageCageDetails> tempList, DownStorageCageDetails cageDetails) {
        //获取2个机械臂范围内的架子绑定的流程卡信息
        List<Integer> workList = new ArrayList();
        if (flag08) {
            if (!"2".equals(glassStatus)) {
                workList.addAll(Const.G11_WORK_STATION);
            }
        } else {
            if (!"2".equals(glassStatus)) {
                workList.addAll(Const.G06_WORK_STATION);
            }
        }
        List<DownStorageCageDetails> list = new ArrayList();
        Boolean isEmptyShelf = Boolean.FALSE;
        //对笼内玻璃进行过滤,仅出符合逻辑的玻璃
        if (CollectionUtils.isNotEmpty(workList)) {
            List<DownWorkstation> downWorkstationList = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
                    .eq(DownWorkstation::getEnableState, 0).in(DownWorkstation::getWorkstationId, workList));
            log.info("架子被禁用,无法出片落架");
            if (CollectionUtils.isEmpty(downWorkstationList)) {
                log.info("笼子被禁用,无法走机械臂下片");
                //走人工下片
                if (!"2".equals(glassStatus13)) {
                    list = tempList.stream().filter(item -> item.getWidth() > maxWidth || item.getHeight() > maxHeight).collect(Collectors.toList());
                }
            } else {
                List<DownWorkstation> workstationsIsNotBind = downWorkstationList.stream().filter(item -> null == (item.getFlowCardId())).collect(Collectors.toList());
                Map<String, List<DownWorkstation>> listMap = downWorkstationList.stream().collect(Collectors.groupingBy(item -> item.getFlowCardId() + ":" + item.getLayer()));
                if (CollectionUtils.isEmpty(workstationsIsNotBind)) {
                    log.info("不存在未绑定流程卡架子");
                    //筛选出对应架子已绑定流程卡可下片的玻璃
                    list = tempList.stream().filter(item -> listMap.containsKey(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
                } else {
                    log.info("存在未绑定流程卡架子,直接获取笼内所有玻璃");
                    isEmptyShelf = Boolean.TRUE;
                    //todo:如果禁用架子已绑定流程卡,因为时间不确定,笼子内的玻璃可重新绑定新架子
//                    list = tempList.stream().filter(item -> !listMap.containsKey(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
                    list = tempList;
                }
            }
        } else {
            if (flag08 && !"2".equals(glassStatus13)) {
                //直接走人工下片
                list = tempList.stream().filter(item -> item.getWidth() > maxWidth || item.getHeight() > maxHeight).collect(Collectors.toList());
            }
        }
        if (CollectionUtils.isEmpty(list)) {
            log.info("笼内玻璃无法执行出片");
            return Boolean.FALSE;
        }
        String tempGlassId = null;
        Boolean isBind = Boolean.FALSE;
        for (DownStorageCageDetails item : list) {
            if (item.getWidth() > maxWidth || item.getHeight() > maxHeight) {
                if (flag08 && !"2".equals(glassStatus13)) {
                    log.info("玻璃宽度或高度超出阈值,执行人工下片");
                    tempGlassId = item.getGlassId();
                    break;
                }
            }
        }
        loop:
        if (tempGlassId == null) {
            //获取正在落架的绑定流程卡的信息(流程卡、层数、落架数量)
            List<DownGlassInfoDTO> downGlassInfoDTOList = downGlassInfoService.queryWorkStationIsIn(Boolean.TRUE);
            List<String> downGlassFlowList = downGlassInfoDTOList.stream().map(item -> item.getFlowCardId() + ":" + item.getLayer()).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(downGlassFlowList)) {
                //架子都未绑定流程卡,出笼内子数量最多尺寸最大的玻璃
                DownStorageCageDetails downStorageCageDetails = downStorageCageDetailsService.getGlassInfoMaxCount();
                //绑定流程卡,更新玻璃状态,生成出片任务,
                tempGlassId = downStorageCageDetails.getGlassId();
                isBind = Boolean.TRUE;
                break loop;
            }
            //将笼子内的玻璃进行过滤,仅获取无法落架的流程卡玻璃
            List<DownStorageCageDetails> noDownLoadList = list.stream().filter(item -> !downGlassFlowList.contains(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noDownLoadList)) {
                //是否有空架子
//                List<DownWorkstation> emptyShelfList = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
//                        .isNull(DownWorkstation::getFlowCardId));
                if (isEmptyShelf) {
                    DownStorageCageDetails downStorageCageDetails = downStorageCageDetailsService.getGlassInfoMaxCount();
                    //绑定流程卡,更新玻璃状态,生成出片任务
                    tempGlassId = downStorageCageDetails.getGlassId();
                    isBind = Boolean.TRUE;
                    break loop;
                }
            }
            //将笼子内的玻璃进行过滤,仅获取可落架的流程卡玻璃
            List<DownStorageCageDetails> downLoadList = list.stream().filter(item -> downGlassFlowList.contains(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(downLoadList)) {
                //不执行出片任务,笼内没有合适的出片玻璃
                return Boolean.FALSE;
            }
            //将笼内玻璃的流程卡+层号 和落架的流程卡 去重,得出展示无法落架的玻璃,判断玻璃数是否超过阈值
            //笼内玻璃是否可落架:笼内是否有需要中空的
            List<DownStorageCageDetails> multiLayerList = list.stream().filter(item -> item.getTotalLayer() >= 2).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(multiLayerList)) {
                for (DownStorageCageDetails item : multiLayerList) {
                    DownGlassInfoDTO downGlassInfoDTO = downGlassInfoService.queryDownGlassMaxLayer(item.getFlowCardId());
                    if (null == downGlassInfoDTO) {
//                    历史落架玻璃按照相关流程卡取数据库未找到最多玻璃信息,表明当前流程卡下的有层的玻璃均未落架,直接可出当前玻璃
                        log.info("");
                        isBind = Boolean.FALSE;
                        tempGlassId = item.getGlassId();
                        break loop;
                    }
                    if (downGlassInfoDTO.getLayer().equals(downGlassInfoDTO.getLayer())) {
                        log.info("当前玻璃的流程在架子上落架最多,直接出片");
                        //更新玻璃状态,生成出片任务
                        tempGlassId = item.getGlassId();
                        isBind = Boolean.FALSE;
                        break loop;
                    }
                    Integer sequence = downGlassInfoService.queryMaxSequence(item.getFlowCardId(), item.getLayer());
                    log.info("获取当前玻璃需要放的次序:笼内同流程 同层数的通达次序+1:{}", sequence);
                    DownGlassInfo downGlassInfo = downGlassInfoService.getOne(new LambdaQueryWrapper<DownGlassInfo>()
                            .eq(DownGlassInfo::getFlowCardId, downGlassInfoDTO.getFlowCardId())
                            .eq(DownGlassInfo::getLayer, downGlassInfoDTO.getLayer()).eq(DownGlassInfo::getSequence, sequence));
                    if (null != downGlassInfoDTO && downGlassInfo.getWidth() == item.getWidth() && downGlassInfo.getHeight() == item.getHeight()) {
                        log.info("相同次序玻璃对应上,可执行进片任务");
                        //更新玻璃状态,生成出片任务
                        tempGlassId = item.getGlassId();
                        isBind = Boolean.FALSE;
                        break loop;
                    }
                }
            }
            Map<String, List<DownStorageCageDetails>> singleLayerMap = list.stream().filter(item -> item.getTotalLayer() == 1)
                    .collect(Collectors.groupingBy(item -> item.getFlowCardId() + item.getLayer(), Collectors.toList()));
            if (tempGlassId == null) {
                if (CollectionUtils.isNotEmpty(singleLayerMap)) {
                    //获取已落架流程卡信息,按落架数量排序
                    for (DownGlassInfoDTO e : downGlassInfoDTOList) {
                        List<DownStorageCageDetails> downStorageCageDetails = singleLayerMap.get(e.getFlowCardId() + e.getLayer());
                        if (CollectionUtils.isNotEmpty(downStorageCageDetails)) {
                            tempGlassId = downStorageCageDetails.get(0).getGlassId();
                            isBind = Boolean.FALSE;
                            break;
                        }
                    }
                }
            }
        }
        if (tempGlassId == null) {
            log.info("没有找到可以下片的的玻璃,结束任务");
            return Boolean.FALSE;
        } else {
            //按照出片的玻璃id更新笼内的玻璃状态为已出片
            return generateDownGlassOutTask(tempGlassId, Const.GLASS_CACHE_TYPE_OUT, isBind, cageDetails);
        }
    }
    public Boolean generateDownGlassOutTask(String glassId, Integer taskType, Boolean isBind, DownStorageCageDetails cageDetails) {
        //按玻璃id获取玻璃信息
        DownStorageCageDetails downStorageCageDetails = null;
        if (glassId.equals(cageDetails.getGlassId())) {
            downStorageCageDetails = cageDetails;
            taskType = 3;
        } else {
            downStorageCageDetails = downStorageCageDetailsService.getOne(new LambdaQueryWrapper<DownStorageCageDetails>()
                    .eq(DownStorageCageDetails::getGlassId, glassId));
        }
        Integer endCell = null;
        if (isBind) {
            //获取空架子信息,将空架子信息绑定流程卡
            DownWorkstation emptyDownWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>()
                    .isNull(DownWorkstation::getFlowCardId).orderByDesc(DownWorkstation::getWorkstationId).last("limit 1"));
            if (null != emptyDownWorkstation) {
                log.info("获取到空架子信息,绑定流程卡");
                emptyDownWorkstation.setFlowCardId(downStorageCageDetails.getFlowCardId());
                emptyDownWorkstation.setLayer(downStorageCageDetails.getLayer());
                downWorkstationService.updateById(emptyDownWorkstation);
                endCell = emptyDownWorkstation.getWorkstationId();
            } else {
                log.info("没有空架子信息,无法绑定流程卡");
                return Boolean.FALSE;
            }
        } else {
            DownWorkstation workstation = downWorkstationService.getOne(new LambdaUpdateWrapper<DownWorkstation>()
                    .eq(DownWorkstation::getFlowCardId, downStorageCageDetails.getFlowCardId()).eq(DownWorkstation::getLayer, downStorageCageDetails.getLayer()));
            endCell = workstation.getWorkstationId();
        }
        //更新详情表内的状态
        if (downStorageCageDetailsService.update(new LambdaUpdateWrapper<DownStorageCageDetails>()
                .set(DownStorageCageDetails::getState, Const.GLASS_STATE_OUT).eq(DownStorageCageDetails::getGlassId, glassId))) {
            log.info("更新详情表内的状态成功");
        } else {
            log.info("更新详情表内的状态失败");
            return Boolean.FALSE;
        }
        //更新落架玻璃数量
        //生成任务信息
        DownGlassInfo downGlassInfo = new DownGlassInfo();
        BeanUtils.copyProperties(downStorageCageDetails, downGlassInfo);
        downGlassInfoService.save(downGlassInfo);
        //生成任务信息
        GlassInfo glassInfo = new GlassInfo();
        BeanUtils.copyProperties(downStorageCageDetails, glassInfo);
        return initDownGlassTask(glassInfo, downStorageCageDetails.getSlot(), endCell, taskType);
    }
    public Boolean initDownGlassTask(GlassInfo glassInfo, Integer startCell, Integer endCell, Integer taskType) {
        log.info("玻璃{}生成进片任务", glassInfo.getGlassId());
        DownGlassTask downGlassTask = new DownGlassTask();
        downGlassTask.setStartCell(startCell);
        downGlassTask.setGlassId(glassInfo.getGlassId());
        downGlassTask.setEndCell(endCell);
        downGlassTask.setTaskType(taskType + "");
        downGlassTask.setWidth((int) glassInfo.getWidth());
        downGlassTask.setHeight((int) glassInfo.getHeight());
        downGlassTask.setFlowCardId(glassInfo.getFlowCardId());
        downGlassTask.setLayer(glassInfo.getLayer());
        downGlassTask.setTaskStauts(0);
        downGlassTask.setCreateTime(new Date());
        downGlassTaskService.save(downGlassTask);
        //向plc发送命令
        return sendMessageToPlc((int) glassInfo.getWidth(), (int) glassInfo.getHeight(), (int) glassInfo.getThickness(),
                startCell, endCell, taskType);
    }
    private Boolean sendMessageToPlc(int width, int height, int thickness, int startCell, int endCell, int taskType) {
        S7control s7control = S7object.getinstance().plccontrol;
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        s7control.writeWord(plcMesObject.getPlcParameter("Glass_width").getAddress(), width);
        s7control.writeWord(plcMesObject.getPlcParameter("Glass_height").getAddress(), height);
        s7control.writeWord(plcMesObject.getPlcParameter("Glass_thickness").getAddress(), thickness);
        s7control.writeWord(plcMesObject.getPlcParameter("Start_cell").getAddress(), startCell);
        s7control.writeWord(plcMesObject.getPlcParameter("End_cell").getAddress(), endCell);
        s7control.writeWord(plcMesObject.getPlcParameter("task_type").getAddress(), taskType);
        s7control.writeWord(plcMesObject.getPlcParameter("confirmationWord").getAddress(), 1);
        return Boolean.TRUE;
    }
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/JsonFile/PlcdownGlass.json
@@ -1,362 +1,144 @@
{
  "plcAddressBegin": "DB100.0",
  "plcAddressLenght": "142",
  "dataType": "word",
  "parameteInfor": [
    {
      "codeId": "RequestWord",
      "addressIndex": "0",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ID",
      "addressIndex": "2",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskRequestWord",
      "addressIndex": "4",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ID",
      "addressIndex": "6",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskRequestWord",
      "addressIndex": "8",
      "addressLenght": "2"
    },
    {
      "codeId": "G011ID",
      "addressIndex": "10",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "12",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "14",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "16",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "18",
      "addressLenght": "2"
    },
    {
      "codeId": "MESSendingWord",
      "addressIndex": "20",
      "addressLenght": "2"
    },
    {
      "codeId": "InputGrid",
      "addressIndex": "22",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputGrid",
      "addressIndex": "24",
      "addressLenght": "2"
    },
    {
      "codeId": "OutputID",
      "addressIndex": "26",
      "addressLenght": "2"
    },
    {
      "codeId": "FrontOrRearLowerSlice",
      "addressIndex": "28",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "30",
      "addressLenght": "2"
    },
    {
      "codeId": "G06RobotTaskReply",
      "addressIndex": "32",
      "addressLenght": "2"
    },
    {
      "codeId": "G06Rack",
      "addressIndex": "34",
      "addressLenght": "2"
    },
    {
      "codeId": "G11RobotTaskReply",
      "addressIndex": "36",
      "addressLenght": "2"
    },
    {
      "codeId": "G11Rack",
      "addressIndex": "38",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "40",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "42",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "44",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "46",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "48",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "50",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "52",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "54",
      "addressLenght": "2"
    },
    {
      "codeId": "MESTaskState",
      "addressIndex": "56",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "58",
      "addressLenght": "2"
    },
    {
      "codeId": "AlarmState",
      "addressIndex": "60",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm1",
      "addressIndex": "62",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm2",
      "addressIndex": "64",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm3",
      "addressIndex": "66",
      "addressLenght": "2"
    },
    {
      "codeId": "Alarm4",
      "addressIndex": "68",
      "addressLenght": "2"
    },
    {
      "codeId": "neirong",
      "addressIndex": "70",
      "addressLenght": "2"
    },
    {
      "codeId": "device",
      "addressIndex": "72",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "74",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "76",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut1",
      "addressIndex": "78",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut2",
      "addressIndex": "80",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut3",
      "addressIndex": "82",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut4",
      "addressIndex": "84",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut5",
      "addressIndex": "86",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut6",
      "addressIndex": "88",
      "addressLenght": "2"
    },
    {
      "codeId": "InOut7",
      "addressIndex": "90",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "92",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "94",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "96",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "98",
      "addressLenght": "2"
    },
    {
      "codeId": "spare",
      "addressIndex": "100",
      "addressLenght": "2"
    },
    {
      "codeId": "G04ActionState",
      "addressIndex": "102",
      "addressLenght": "2"
    },
    {
      "codeId": "G05ActionState",
      "addressIndex": "104",
      "addressLenght": "2"
    },
    {
      "codeId": "G06ActionState",
      "addressIndex": "106",
      "addressLenght": "2"
    },
    {
      "codeId": "G07ActionState",
      "addressIndex": "108",
      "addressLenght": "2"
    },
    {
      "codeId": "G08ActionState",
      "addressIndex": "110",
      "addressLenght": "2"
    },
    {
      "codeId": "G09ActionState",
      "addressIndex": "112",
      "addressLenght": "2"
    },
    {
      "codeId": "G10ActionState",
      "addressIndex": "114",
      "addressLenght": "2"
    },
    {
      "codeId": "G11ActionState",
      "addressIndex": "116",
      "addressLenght": "2"
    },
    {
      "codeId": "G12ActionState",
      "addressIndex": "118",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ActionState",
      "addressIndex": "120",
      "addressLenght": "2"
    },
    {
      "codeId": "G04IDS",
      "addressIndex": "122",
      "addressLenght": "2"
    },
    {
      "codeId": "G05IDS",
      "addressIndex": "124",
      "addressLenght": "2"
    },
    {
      "codeId": "G06IDS",
      "addressIndex": "126",
      "addressLenght": "2"
    },
    {
      "codeId": "G07IDS",
      "addressIndex": "128",
      "addressLenght": "2"
    },
    {
      "codeId": "G08IDS",
      "addressIndex": "130",
      "addressLenght": "2"
    },
    {
      "codeId": "G09IDS",
      "addressIndex": "132",
      "addressLenght": "2"
    },
    {
      "codeId": "G10IDS",
      "addressIndex": "134",
      "addressLenght": "2"
    },
    {
      "codeId": "G11IDS",
      "addressIndex": "136",
      "addressLenght": "2"
    },
    {
      "codeId": "G12IDS",
      "addressIndex": "138",
      "addressLenght": "2"
    },
    {
      "codeId": "G13ID",
      "addressIndex": "140",
      "addressLenght": "2"
    }
  ]
    "plcAddressBegin": "DB11.0",
    "plcAddressLenght": "100",
    "dataType": "word",
    "parameteInfor": [
        {
            "codeId": "requestWord",
            "addressIndex": "0",
            "addressLenght": "2"
        },
        {
            "codeId": "requestID",
            "addressIndex": "2",
            "addressLenght": "30"
        },
        {
            "codeId": "currentCell",
            "addressIndex": "32",
            "addressLenght": "2"
        },
        {
            "codeId": "glassStatus08",
            "addressIndex": "36",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_glass_status",
            "addressIndex": "40",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_glass_status",
            "addressIndex": "42",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_glass_status",
            "addressIndex": "44",
            "addressLenght": "2"
        },
        {
            "codeId": "G04_error_status",
            "addressIndex": "48",
            "addressLenght": "2"
        },
        {
            "codeId": "G05_error_status",
            "addressIndex": "50",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_error_status",
            "addressIndex": "52",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "54",
            "addressLenght": "2"
        },
        {
            "codeId": "G08_error_status",
            "addressIndex": "56",
            "addressLenght": "2"
        },
        {
            "codeId": "G09_error_status",
            "addressIndex": "58",
            "addressLenght": "2"
        },
        {
            "codeId": "G10_error_status",
            "addressIndex": "60",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_error_status",
            "addressIndex": "62",
            "addressLenght": "2"
        },
        {
            "codeId": "robot_error_status",
            "addressIndex": "64",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_error_status",
            "addressIndex": "66",
            "addressLenght": "2"
        },
        {
            "codeId": "confirmationWord",
            "addressIndex": "72",
            "addressLenght": "2"
        },
        {
            "codeId": "G06_prohibit_film_production",
            "addressIndex": "74",
            "addressLenght": "2"
        },
        {
            "codeId": "G11_prohibit_film_production",
            "addressIndex": "76",
            "addressLenght": "2"
        },
        {
            "codeId": "G13_prohibit_film_production",
            "addressIndex": "78",
            "addressLenght": "2"
        },
        {
            "codeId": "Glass_width",
            "addressIndex": "82",
            "addressLenght": "4"
        },
        {
            "codeId": "Glass_height",
            "addressIndex": "86",
            "addressLenght": "4"
        },
        {
            "codeId": "Glass_thickness",
            "addressIndex": "90",
            "addressLenght": "4"
        },
        {
            "codeId": "Start_cell",
            "addressIndex": "94",
            "addressLenght": "2"
        },
        {
            "codeId": "End_cell",
            "addressIndex": "96",
            "addressLenght": "2"
        },
        {
            "codeId": "task_type",
            "addressIndex": "98",
            "addressLenght": "2"
        }
    ]
}
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application-cz.yml
@@ -10,7 +10,7 @@
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
        salve_hangzhoumes:
          url: jdbc:sqlserver://192.168.10.2:1433;databasename=hangzhoumes
          url: jdbc:sqlserver://192.168.30.101:1433;databasename=hangzhoumes
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application-prod.yml
@@ -14,6 +14,11 @@
          username: sa
          password: beibo.123/
          driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        pp:
          url: jdbc:mysql://10.153.19.150:3306/pp?serverTimezone=GMT%2b8
          username: root
          password: beibo.123/
          driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/application.yml
@@ -3,7 +3,7 @@
spring:
  profiles:
    active: cz
    active: dev
  application:
    name: unLoadGlass
@@ -12,3 +12,10 @@
  mapper-locations: classpath*:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mes:
  maxWidth: 1000    #下片的最大宽度
  maxHeight: 1000   #下片的最大高度
  throughWidth: 3000
  throughHeight: 3000
  threshold: 5      #下片的最大阈值
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/mapper/DownGlassInfoMapper.xml
New file
@@ -0,0 +1,75 @@
<?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 namespace="com.mes.downglassinfo.mapper.DownGlassInfoMapper">
    <resultMap id="downGlassInfoDTO" type="com.mes.downworkstation.entity.dto.DownGlassInfoDTO">
        <result column="flow_card_id" property="flowCardId"/>
        <result column="layer" property="layer"/>
        <result column="count" property="count"/>
    </resultMap>
    <resultMap id="downGlassInfo" type="com.mes.downworkstation.entity.dto.DownGlassInfoDTO">
        <result column="flow_card_id" property="flowCardId"/>
        <result column="layer" property="layer"/>
        <result column="count" property="count"/>
        <collection property="glassInfoList" ofType="com.mes.glassinfo.entity.GlassInfo">
            <id column="id" property="id"/>
            <result column="flow_card_id" property="flowCardId"/>
            <result column="glass_type" property="glassType"/>
            <result column="width" property="width"/>
            <result column="height" property="height"/>
            <result column="thickness" property="thickness"/>
            <result column="filmsid" property="filmsid"/>
            <result column="total_layer" property="totalLayer"/>
            <result column="layer" property="layer"/>
        </collection>
    </resultMap>
    <select id="queryDownGlassMaxLayer" resultMap="downGlassInfoDTO">
        SELECT flow_card_id,
               layer,
               COUNT(layer) AS count
        FROM
            down_glass_info
        WHERE
            flow_card_id = #{flowCardId}
        GROUP BY
            flow_card_id,
            layer
        order by count desc limit 1
    </select>
    <select id="queryMaxSequence" resultType="java.lang.Integer">
        SELECT max(sequence) + 1 as sequence
        FROM down_glass_info
        WHERE flow_card_id = #{flowCardId}
          AND layer = #{layer}
    </select>
    <select id="queryWorkStationIsIn" resultMap="downGlassInfo">
        SELECT T.*
        <if test="!isDownload">
            ,T1.*
        </if>
        FROM (
        SELECT T.FLOW_CARD_ID,
        T.LAYER,
        COUNT(T.LAYER) AS COUNT
        FROM
        DOWN_WORKSTATION T
        LEFT JOIN DOWN_GLASS_INFO T1 ON T.FLOW_CARD_ID = T1.FLOW_CARD_ID
        GROUP BY T.FLOW_CARD_ID,LAYER
        HAVING T.FLOW_CARD_ID IS NOT NULL
        ) T
        INNER JOIN GLASS_INFO T1 ON T.FLOW_CARD_ID = T1.FLOW_CARD_ID
        AND T.LAYER = T1.LAYER
        LEFT JOIN DOWN_GLASS_INFO T2 ON T1.GLASS_ID = T2.GLASS_ID
        <where>
            <if test="isDownload">
                AND T2.GLASS_ID IS NULL
            </if>
            <if test="!isDownload">
                AND T2.GLASS_ID IS not NULL
            </if>
        </where>
        order by t.count desc
    </select>
</mapper>
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/resources/mapper/DownStorageCageDetailsMapper.xml
New file
@@ -0,0 +1,41 @@
<?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 namespace="com.mes.downstorage.mapper.DownStorageCageDetailsMapper">
    <resultMap id="downStorageCageDetails" type="com.mes.downstorage.entity.DownStorageCageDetails">
        <id column="id" property="id"/>
        <result column="slot" property="slot"/>
        <result column="glass_id" property="glassId"/>
        <result column="sequence" property="sequence"/>
        <result column="filmsid" property="filmsid"/>
        <result column="flow_card_id" property="flowCardId"/>
        <result column="glass_type" property="glassType"/>
        <result column="width" property="width"/>
        <result column="height" property="height"/>
        <result column="thickness" property="thickness"/>
        <result column="tempering_layout_id" property="temperingLayoutId"/>
        <result column="tempering_feed_sequence" property="temperingFeedSequence"/>
        <result column="state" property="state"/>
        <result column="gap" property="gap"/>
        <result column="total_layer" property="totalLayer"/>
        <result column="layer" property="layer"/>
    </resultMap>
    <select id="getGlassInfoMaxCount" resultMap="downStorageCageDetails">
        SELECT *
        FROM DOWN_STORAGE_CAGE_DETAILS
        WHERE (FLOW_CARD_ID, LAYER) = (SELECT FLOW_CARD_ID, LAYER
                                       FROM DOWN_STORAGE_CAGE_DETAILS
                                       WHERE STATE = 100
                                       GROUP BY FLOW_CARD_ID, LAYER
                                       ORDER BY COUNT(FLOW_CARD_ID) DESC
            LIMIT 1 )
          AND STATE = 100
        ORDER BY
            WIDTH DESC,
            HEIGHT DESC
            LIMIT 1
    </select>
</mapper>
hangzhoumesParent/moduleService/UnLoadGlassModule/src/test/java/mes/UnloadGlassModuleApplicationTest.java
@@ -1,6 +1,8 @@
package mes;
import com.mes.UnLoadGlassApplication;
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.downglassinfo.service.impl.DownGlassInfoServiceImpl;
import com.mes.downglassinfo.service.impl.DownGlassTaskServiceImpl;
import com.mes.downstorage.entity.DownStorageCage;
@@ -36,7 +38,7 @@
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = UnLoadGlassApplication.class)
@SpringBootTest(classes = UnLoadGlassApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UnloadGlassModuleApplicationTest {
@@ -58,6 +60,10 @@
    DownWorkstationService downWorkstationService;
    @Autowired
    DownStorageCageService downStorageCageService;
    @Autowired
    DownGlassTaskService downGlassTaskService;
    @Autowired
    DownGlassInfoService downGlassInfoService;
@@ -150,7 +156,7 @@
    public void getMaxSequenceByFlowCardId() {
        log.info("最大序号");
        downGlassInfoServiceImpl.getMaxSequenceByFlowCardId("NG2023005");
        downGlassInfoServiceImpl.getMaxSequenceByFlowCardId("NG2023005",1);
    }
    @Test
@@ -171,8 +177,16 @@
    @Test
    public void getFlowCardId() {
        glassInfoServiceImpl.getFlowCardId();
    }
    @Test
    public void getUnloadingTaskState() {
        downGlassInfoService.generateOutGlassTask("NG24031401A01-4-3-1-3");
        //downGlassTaskService.getUnloadingTaskState();
    }
    @Test