diff --git a/hw-modules/hw-mes/src/main/java/com/hw/mes/controller/MesProductOrderController.java b/hw-modules/hw-mes/src/main/java/com/hw/mes/controller/MesProductOrderController.java index 382066f5..c221d90d 100644 --- a/hw-modules/hw-mes/src/main/java/com/hw/mes/controller/MesProductOrderController.java +++ b/hw-modules/hw-mes/src/main/java/com/hw/mes/controller/MesProductOrderController.java @@ -51,6 +51,20 @@ public class MesProductOrderController extends BaseController { return getDataTable(list); } + /** + * 查询生产工单列表 + * 前置任务、后置任务 + * @param mesProductOrder + * @return + */ + @RequiresPermissions("mes:productOrder:list") + @GetMapping("/allList") + public AjaxResult allList(MesProductOrder mesProductOrder) + { + List list = mesProductOrderService.selectAllListTaskList(mesProductOrder); + return success(list); + } + /** * 导出生产工单列表 */ @@ -94,6 +108,21 @@ public class MesProductOrderController extends BaseController { return toAjax(mesProductOrderService.updateMesProductOrder(mesProductOrder)); } + /** + * 批量修改生产工单 + * @param productOrderList + * @return + */ + @PostMapping("/batchEditingProductOrder") + public AjaxResult batchEditingProductOrder(@RequestBody List productOrderList) { + int result = 0; + for (MesProductOrder productOrder : productOrderList) { + productOrder.setUpdateBy(SecurityUtils.getLoginUser().getUsername()); + result = mesProductOrderService.updateMesProductOrder(productOrder); + } + return toAjax(result); + } + /** * 删除生产工单 */ diff --git a/hw-modules/hw-mes/src/main/java/com/hw/mes/domain/MesProductOrder.java b/hw-modules/hw-mes/src/main/java/com/hw/mes/domain/MesProductOrder.java index 53f3d0f9..dd884d6e 100644 --- a/hw-modules/hw-mes/src/main/java/com/hw/mes/domain/MesProductOrder.java +++ b/hw-modules/hw-mes/src/main/java/com/hw/mes/domain/MesProductOrder.java @@ -197,6 +197,34 @@ public class MesProductOrder extends BaseEntity { @Excel(name = "单位时间") private Long productionTime; + /** + * 前置生产工单ID + */ + @Excel(name = "前置生产工单ID") + private Long preOrderId; + + /** + * 前置生产工单编号 + */ + @Excel(name = "前置生产工单编号") + private String preOrderCode; + + public String getPreOrderCode() { + return preOrderCode; + } + + public void setPreOrderCode(String preOrderCode) { + this.preOrderCode = preOrderCode; + } + + public Long getPreOrderId() { + return preOrderId; + } + + public void setPreOrderId(Long preOrderId) { + this.preOrderId = preOrderId; + } + public Long getProductionTime() { return productionTime; } diff --git a/hw-modules/hw-mes/src/main/java/com/hw/mes/mapper/MesProductOrderMapper.java b/hw-modules/hw-mes/src/main/java/com/hw/mes/mapper/MesProductOrderMapper.java index 4d42e19c..aff3c8c4 100644 --- a/hw-modules/hw-mes/src/main/java/com/hw/mes/mapper/MesProductOrderMapper.java +++ b/hw-modules/hw-mes/src/main/java/com/hw/mes/mapper/MesProductOrderMapper.java @@ -59,8 +59,6 @@ public interface MesProductOrderMapper */ public int deleteMesProductOrderByProductOrderIds(Long[] productOrderIds); - - /** * 查询生产工单 * @@ -69,4 +67,11 @@ public interface MesProductOrderMapper */ public MesProductOrder selectMesProductOrderByPlanCode(String planCode); + /** + * productOrderId为父级的子生产工单列表 + * @param productOrderId + * @return + */ + List selectMesProductOrderListByPreOrderId(Long productOrderId); + } diff --git a/hw-modules/hw-mes/src/main/java/com/hw/mes/service/IMesProductOrderService.java b/hw-modules/hw-mes/src/main/java/com/hw/mes/service/IMesProductOrderService.java index 48441abd..c1c06810 100644 --- a/hw-modules/hw-mes/src/main/java/com/hw/mes/service/IMesProductOrderService.java +++ b/hw-modules/hw-mes/src/main/java/com/hw/mes/service/IMesProductOrderService.java @@ -87,4 +87,12 @@ public interface IMesProductOrderService * @return */ public Boolean verifyBOMIsProduction(Long materialBomId); + + /** + * 查询生产工单列表 + * 前置任务、后置任务 + * @param mesProductOrder + * @return + */ + public List selectAllListTaskList(MesProductOrder mesProductOrder); } diff --git a/hw-modules/hw-mes/src/main/java/com/hw/mes/service/impl/MesProductOrderServiceImpl.java b/hw-modules/hw-mes/src/main/java/com/hw/mes/service/impl/MesProductOrderServiceImpl.java index d8ebae2b..c59549f5 100644 --- a/hw-modules/hw-mes/src/main/java/com/hw/mes/service/impl/MesProductOrderServiceImpl.java +++ b/hw-modules/hw-mes/src/main/java/com/hw/mes/service/impl/MesProductOrderServiceImpl.java @@ -1,7 +1,10 @@ package com.hw.mes.service.impl; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.hw.common.core.constant.MesConstants; import com.hw.common.core.exception.ServiceException; @@ -219,4 +222,53 @@ public class MesProductOrderServiceImpl implements IMesProductOrderService { return false; } + /** + * 查询生产工单列表 + * 前置任务、后置任务 + * @param mesProductOrder + * @return + */ + @Override + public List selectAllListTaskList(MesProductOrder mesProductOrder) { + Long productOrderId = mesProductOrder.getProductOrderId(); + // 结果列表,用于存储所有关联的订单 + List result = new ArrayList<>(); + // 记录已经访问过的订单ID,防止重复访问 + Set visited = new HashSet<>(); + // 从给定的productOrderId开始,找到最顶级节点 + MesProductOrder topLevelOrder = findTopLevelOrder(productOrderId); + // 从最顶级节点开始递归遍历所有子节点 + if (topLevelOrder != null) { + traverseChildren(result, topLevelOrder, visited); + } + // 返回包含所有关联订单的结果列表 + return result; + } + + // 递归查找最顶级节点 + private MesProductOrder findTopLevelOrder(Long productOrderId) { + MesProductOrder currentOrder = mesProductOrderMapper.selectMesProductOrderByProductOrderId(productOrderId); + while (currentOrder != null && currentOrder.getPreOrderId() != null) { + currentOrder = mesProductOrderMapper.selectMesProductOrderByProductOrderId(currentOrder.getPreOrderId()); + } + return currentOrder; + } + + // 递归遍历子级节点 + private void traverseChildren(List result, MesProductOrder currentOrder, Set visited) { + if (currentOrder == null || visited.contains(currentOrder.getProductOrderId())) { + return; + } + // 将当前订单添加到结果列表 + result.add(currentOrder); + // 将当前订单的ID添加到访问集合中 + visited.add(currentOrder.getProductOrderId()); + // 获取所有以当前订单为父级ID的子订单列表 + List children = mesProductOrderMapper.selectMesProductOrderListByPreOrderId(currentOrder.getProductOrderId()); + for (MesProductOrder child : children) { + // 递归遍历每个子订单 + traverseChildren(result, child, visited); + } + } + } diff --git a/hw-modules/hw-mes/src/main/resources/mapper/mes/MesProductOrderMapper.xml b/hw-modules/hw-mes/src/main/resources/mapper/mes/MesProductOrderMapper.xml index 24980d36..1201c7ea 100644 --- a/hw-modules/hw-mes/src/main/resources/mapper/mes/MesProductOrderMapper.xml +++ b/hw-modules/hw-mes/src/main/resources/mapper/mes/MesProductOrderMapper.xml @@ -39,6 +39,7 @@ + @@ -75,6 +76,7 @@ mpo.create_time, mpo.update_by, mpo.update_time, + mpo.pre_order_id, mbr.production_time from mes_product_order mpo left join (select a.route_id, @@ -115,6 +117,7 @@ and mpo.order_status = #{orderStatus} and mpo.stock_lock_flag = #{stockLockFlag} and mpo.sale_order_flag = #{saleOrderFlag} + and mpo.pre_order_id = #{preOrderId} and mpo.create_by = #{createBy} and mpo.create_time = #{createTime} and mpo.update_by = #{updateBy} @@ -160,6 +163,7 @@ update_by, update_time, plan_delivery_date, + pre_order_id, #{orderCode}, @@ -190,6 +194,7 @@ #{updateBy}, #{updateTime}, #{planDeliveryDate}, + #{preOrderId}, @@ -224,6 +229,7 @@ update_by = #{updateBy}, update_time = #{updateTime}, plan_delivery_date = #{planDeliveryDate}, + pre_order_id = #{preOrderId}, where product_order_id = #{productOrderId} @@ -258,4 +264,9 @@ limit 1 + + diff --git a/hw-ui/.gitignore b/hw-ui/.gitignore index 43079d91..8dbf5e88 100644 --- a/hw-ui/.gitignore +++ b/hw-ui/.gitignore @@ -22,4 +22,4 @@ selenium-debug.log package-lock.json yarn.lock -vue.config.js + diff --git a/hw-ui/src/api/mes/productOrder.js b/hw-ui/src/api/mes/productOrder.js index 7b7d7afc..6a47b1fc 100644 --- a/hw-ui/src/api/mes/productOrder.js +++ b/hw-ui/src/api/mes/productOrder.js @@ -96,3 +96,21 @@ export function getSaleOrders(query) { params: query }) } + +// 查询生产工单列表 不分页 +export function allListProductOrder(query) { + return request({ + url: '/mes/productOrder/allList', + method: 'get', + params: query + }) +} + +// 批量修改生产工单 +export function batchEditingProductOrder(data) { + return request({ + url: '/mes/productOrder/batchEditingProductOrder', + method: 'post', + data: data + }) +} diff --git a/hw-ui/src/router/index.js b/hw-ui/src/router/index.js index 7baa9e58..aae88c24 100644 --- a/hw-ui/src/router/index.js +++ b/hw-ui/src/router/index.js @@ -296,6 +296,20 @@ export const dynamicRoutes = [ } ] }, + { + path: '/mes/production-scheduling', + component: Layout, + hidden: true, + permissions: ['mes:productplan:edit'], + children: [ + { + path: 'index/:productOrderId(\\d+)', + component: () => import('@/views/mes/productOrder/productionScheduling'), + name: 'productionScheduling', + meta: { title: '工单排产', activeMenu: '/mes/productionScheduling' } + } + ] + }, //查看工单路由,不可审批 { path: "/dms/repairInstanceActivitySelect", diff --git a/hw-ui/src/views/board/model/agv.js b/hw-ui/src/views/board/model/agv.js index 640ae23b..2832b764 100644 --- a/hw-ui/src/views/board/model/agv.js +++ b/hw-ui/src/views/board/model/agv.js @@ -1,23 +1,37 @@ import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import * as THREE from 'three' -import { camera, labelRenderer, renderer, scene } from '@/views/board/model/setThree' +import { camera, labelRenderer, renderer, scene,isLoading } from '@/views/board/model/setThree' import * as TWEEN from '@tweenjs/tween.js' let timeOrSpeed = true -let isAGVAnimation = false -let AGVanimationLine = [] +let isAGVAnimation = { + '2AGV': false, + '3AGV': false, + '5CCAGV': false, + '5BFAGV': false, + '5CTU': false +} +let AGVanimationLine = { + '2AGV': [], + '3AGV': [], + '5CCAGV': [], + '5BFAGV': [], + '5CTU': [] +} + +let animationEnum = ['2AGV', '3AGV', '5CCAGV', '5BFAGV', '5CTU'] -const AGVanimation = async() => { +const AGVanimation = async(e) => { try { - if (AGVanimationLine.length > 0) { - await AGVanimationLine[0]() - AGVanimationLine.shift() - if (AGVanimationLine.length > 0) { - AGVanimation(AGVanimationLine) + if (AGVanimationLine[e].length > 0) { + await AGVanimationLine[e][0]() + AGVanimationLine[e].shift() + if (AGVanimationLine[e].length > 0) { + AGVanimation(e) } else { - isAGVAnimation = false + isAGVAnimation[e] = false } } } catch (e) { @@ -26,14 +40,13 @@ const AGVanimation = async() => { } function AGVanimate() { - if (AGVanimationLine.length > 0 && isAGVAnimation === false) { - isAGVAnimation = true - AGVanimation(AGVanimationLine) - } + animationEnum.forEach(e => { + if (AGVanimationLine[e].length > 0 && isAGVAnimation[e] === false) { + isAGVAnimation[e] = true + AGVanimation(e) + } + }) requestAnimationFrame(AGVanimate) - TWEEN.update() - renderer.render(scene, camera) - labelRenderer.render(scene, camera) } AGVanimate() @@ -62,6 +75,7 @@ let agvData = { rotate: 0 }, floor2AGVGroupLocation: {}, + floor3AGVGroup: null, floor3AGV: null, floor3AGVData: { @@ -70,6 +84,7 @@ let agvData = { rotate: 0 }, floor3AGVGroupLocation: {}, + floor5CCAGVGroup: null, floor5CCAGV: null, floor5CCAGVGroupLocation: {}, @@ -78,6 +93,7 @@ let agvData = { y: 0, rotate: 0 }, + floor5BFAGVGroup: null, floor5BFAGV: null, floor5BFAGVGroupLocation: {}, @@ -86,6 +102,7 @@ let agvData = { y: 0, rotate: 0 }, + floor5CTUGroup: null, floor5CTU: null, floor5CTUGroupLocation: {}, @@ -93,7 +110,7 @@ let agvData = { x: 0, y: 0, rotate: 0 - }, + } } let loadAGVEnum = { @@ -101,46 +118,49 @@ let loadAGVEnum = { 'chacheshiAGV005': 'floor5CCAGV', 'CTU005': 'floor5CTU', 'chacheshiAGV002': 'floor2AGV', - 'chacheshiAGV003': 'floor3AGV', + 'chacheshiAGV003': 'floor3AGV' } let loadAGVGroupEnum = { 'beifushiAGV005': 'floor5BFAGVGroup', 'chacheshiAGV005': 'floor5CCAGVGroup', 'CTU005': 'floor5CTUGroup', 'chacheshiAGV002': 'floor2AGVGroup', - 'chacheshiAGV003': 'floor3AGVGroup', + 'chacheshiAGV003': 'floor3AGVGroup' } let LoadAGVDataEnum = { 'beifushiAGV005': 'floor5BFAGVData', 'chacheshiAGV005': 'floor5CCAGVData', 'CTU005': 'floor5CTUData', 'chacheshiAGV002': 'floor2AGVData', - 'chacheshiAGV003': 'floor3AGVData', + 'chacheshiAGV003': 'floor3AGVData' } let LoadAGVLocationEnum = { 'beifushiAGV005': 'floor5BFAGVGroupLocation', 'chacheshiAGV005': 'floor5CCAGVGroupLocation', 'CTU005': 'floor5CTUGroupLocation', 'chacheshiAGV002': 'floor2AGVGroupLocation', - 'chacheshiAGV003': 'floor3AGVGroupLocation', + 'chacheshiAGV003': 'floor3AGVGroupLocation' } let axisEnum = { - 'beifushiAGV005':{ - z : 11.6 - }, 'chacheshiAGV002': { - // z : 11.6 + x: 9, + z: 15 }, 'chacheshiAGV003': { - // z : 11.6 + x: 9, + z: 20.5 + }, + 'beifushiAGV005': { + z: 11.6 }, 'chacheshiAGV005': { - // z : 11.6 + x: 9, + z: 22 }, 'CTU005': { - x:-5, - z : -20 - }, + x: -3.5, + z: -20 + } } const loadAGV = (r) => { r.forEach(e => { @@ -164,10 +184,9 @@ const loadAGV = (r) => { axis.applyMatrix4(object.children[0].matrixWorld) agvData[agvGroupName] = new THREE.Group() - console.log(object) agvData[agvGroupName].add(object) let axisDis = axisEnum[e] - Object.keys(axisDis || {}).forEach(v=>{ + Object.keys(axisDis || {}).forEach(v => { axis[v] += axisDis[v] }) agvData[agvGroupName].position.set(axis.x, axis.y, axis.z) @@ -188,36 +207,36 @@ const loadAGV = (r) => { }) }) } -// loadAGV(['chacheshiAGV002','chacheshiAGV003','chacheshiAGV005','beifushiAGV005','CTU005']) -loadAGV(['CTU005']) +loadAGV(['chacheshiAGV002', 'chacheshiAGV003', 'chacheshiAGV005', 'beifushiAGV005', 'CTU005']) +// loadAGV(['chacheshiAGV003']) let AGVGroupEnum = { '5BFAGV': 'floor5BFAGVGroupLocation', '5CCAGV': 'floor5CCAGVGroupLocation', '5CTU': 'floor5CTUGroupLocation', '2AGV': 'floor2AGVGroupLocation', - '3AGV': 'floor3AGVGroupLocation', + '3AGV': 'floor3AGVGroupLocation' } let AGVDataEnum = { '5BFAGV': 'floor5BFAGVData', '5CCAGV': 'floor5CCAGVData', '5CTU': 'floor5CTUData', '2AGV': 'floor2AGVData', - '3AGV': 'floor3AGVData', + '3AGV': 'floor3AGVData' } let groupEnum = { '5BFAGV': 'floor5BFAGVGroup', '5CCAGV': 'floor5CCAGVGroup', '5CTU': 'floor5CTUGroup', '2AGV': 'floor2AGVGroup', - '3AGV': 'floor3AGVGroup', + '3AGV': 'floor3AGVGroup' } let floorEnum = { '5BFAGV': 'floor5Data', '5CCAGV': 'floor5Data', '5CTU': 'floor5Data', '2AGV': 'floor2Data', - '3AGV': 'floor3Data', + '3AGV': 'floor3Data' } let rotateF = (e) => { e %= 360 @@ -233,10 +252,10 @@ let rotateF = (e) => { const AGVAnimationF = (item, type, newLocation = 0, time = 2000) => { let s = 1 newLocation %= 360 - if((item === '2AGV' || item === '3AGV'|| item === '5CCAGV') && type === 'rotate'){ + if ((item === '2AGV' || item === '3AGV' || item === '5CCAGV') && type === 'rotate') { newLocation -= 90 } - if((item === '5CTU' ) && type === 'rotate'){ + if ((item === '5CTU') && type === 'rotate') { newLocation += 90 } let AGVGroupLocationData = AGVGroupEnum[item] @@ -256,41 +275,50 @@ const AGVAnimationF = (item, type, newLocation = 0, time = 2000) => { resolve() } let distance = location - agvData[AGVLocationData].x - - let time1 = setInterval(() => { - if ((distance > 0 && agvData[group].position.x >= location) || (distance < 0 && agvData[group].position.x <= location)) { + let tween = new TWEEN.Tween(agvData[group].position) + .to({ x: location }, Math.abs(distance) / s * 16) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { agvData[group].position.x = location agvData[AGVLocationData].x = location resolve() - clearInterval(time1) - clearTimeout(time3) - } else { - if (timeOrSpeed) { - if ((agvData[group].position.x - location) < 0) { - agvData[group].position.x += s - } else { - agvData[group].position.x -= s - } - } else { - agvData[group].position.x += distance / (time / 16) - } - - agvData[AGVLocationData].x = agvData[group].position.x - } - }, 16) - let intervalTime - if (timeOrSpeed) { - intervalTime = (distance / ((((agvData[group].position.x - location) < 0) ? 1 : -1) * s) * 16) + 1000 - } else { - intervalTime = time + 1000 - } - let time3 = setTimeout(() => { - agvData[group].position.x = location - agvData[AGVLocationData].x = location - resolve() - clearInterval(time1) - clearTimeout(time3) - }, intervalTime) + tween.stop() + tween = null + }) + .start() // 立即开始动画 + // let time1 = setInterval(() => { + // if ((distance > 0 && agvData[group].position.x >= location) || (distance < 0 && agvData[group].position.x <= location)) { + // agvData[group].position.x = location + // agvData[AGVLocationData].x = location + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // } else { + // if (timeOrSpeed) { + // if ((agvData[group].position.x - location) < 0) { + // agvData[group].position.x += s + // } else { + // agvData[group].position.x -= s + // } + // } else { + // agvData[group].position.x += distance / (time / 16) + // } + // + // agvData[AGVLocationData].x = agvData[group].position.x + // } + // }, 16) + // let intervalTime + // if (timeOrSpeed) { + // intervalTime = (distance / ((((agvData[group].position.x - location) < 0) ? 1 : -1) * s) * 16) + 1000 + // } else { + // intervalTime = time + 1000 + // } + // let time3 = setTimeout(() => { + // agvData[group].position.x = location + // agvData[AGVLocationData].x = location + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // }, intervalTime) }) } case 'z': { @@ -306,41 +334,51 @@ const AGVAnimationF = (item, type, newLocation = 0, time = 2000) => { } let distance = location - agvData[AGVLocationData].z - let time1 = setInterval(() => { - if ((distance > 0 && agvData[group].position.z >= location) || (distance < 0 && agvData[group].position.z <= location)) { + let tween = new TWEEN.Tween(agvData[group].position) + .to({ z: location }, Math.abs(distance) / s * 16) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { agvData[group].position.z = location agvData[AGVLocationData].z = location resolve() - clearInterval(time1) - clearTimeout(time3) - } else { - - if (timeOrSpeed) { - if ((agvData[group].position.z - location) < 0) { - agvData[group].position.z += s - } else { - agvData[group].position.z -= s - } - } else { - agvData[group].position.z += distance / (time / 16) - } - - agvData[AGVLocationData].z = agvData[group].position.z - } - }, 16) - let intervalTime - if (timeOrSpeed) { - intervalTime = (distance / ((((agvData[group].position.z - location) < 0) ? 1 : -1) * s) * 16) + 1000 - } else { - intervalTime = time + 1000 - } - let time3 = setTimeout(() => { - agvData[group].position.z = location - agvData[AGVLocationData].z = location - resolve() - clearInterval(time1) - clearTimeout(time3) - }, intervalTime) + tween.stop() + tween = null + }) + .start() + // let time1 = setInterval(() => { + // if ((distance > 0 && agvData[group].position.z >= location) || (distance < 0 && agvData[group].position.z <= location)) { + // agvData[group].position.z = location + // agvData[AGVLocationData].z = location + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // } else { + // + // if (timeOrSpeed) { + // if ((agvData[group].position.z - location) < 0) { + // agvData[group].position.z += s + // } else { + // agvData[group].position.z -= s + // } + // } else { + // agvData[group].position.z += distance / (time / 16) + // } + // + // agvData[AGVLocationData].z = agvData[group].position.z + // } + // }, 16) + // let intervalTime + // if (timeOrSpeed) { + // intervalTime = (distance / ((((agvData[group].position.z - location) < 0) ? 1 : -1) * s) * 16) + 1000 + // } else { + // intervalTime = time + 1000 + // } + // let time3 = setTimeout(() => { + // agvData[group].position.z = location + // agvData[AGVLocationData].z = location + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // }, intervalTime) }) } case 'rotate': { @@ -354,23 +392,32 @@ const AGVAnimationF = (item, type, newLocation = 0, time = 2000) => { let endRotateNum = nowRotateNum + (distance * (Math.PI / 180)) let bool = (nowRotateNum - endRotateNum) > 0 - let time1 = setInterval(() => { - if ((bool && nowRotateNum < endRotateNum) || (!bool && nowRotateNum > endRotateNum)) { + let tween = new TWEEN.Tween(agvData[group].rotation) + .to({ y: newLocation * (Math.PI / 180) }, 500) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { agvData[group].rotation.y = (newLocation * (Math.PI / 180)) resolve() - clearInterval(time1) - clearTimeout(time2) - } else { - agvData[group].rotation.y += ((distance / (500 / 16)) * (Math.PI / 180)) - nowRotateNum += ((distance / (500 / 16)) * (Math.PI / 180)) - } - }, 16) - let time2 = setTimeout(() => { - agvData[group].rotation.y = (newLocation * (Math.PI / 180)) - resolve() - clearInterval(time1) - clearTimeout(time2) - }, 500 + 1000) + tween.stop() + tween = null + }) + .start() + // let time1 = setInterval(() => { + // if ((bool && nowRotateNum < endRotateNum) || (!bool && nowRotateNum > endRotateNum)) { + // agvData[group].rotation.y = (newLocation * (Math.PI / 180)) + // resolve() + // clearInterval(time1) + // clearTimeout(time2) + // } else { + // agvData[group].rotation.y += ((distance / (500 / 16)) * (Math.PI / 180)) + // nowRotateNum += ((distance / (500 / 16)) * (Math.PI / 180)) + // } + // }, 16) + // let time2 = setTimeout(() => { + // agvData[group].rotation.y = (newLocation * (Math.PI / 180)) + // resolve() + // clearInterval(time1) + // clearTimeout(time2) + // }, 500 + 1000) }) } @@ -382,82 +429,62 @@ const AGVAnimationF = (item, type, newLocation = 0, time = 2000) => { } } -const AGVAnimation = (item, type, newLocation = 0, time = 2000) => { - AGVanimationLine.push(() => AGVAnimationF(item, type, newLocation, time)) +const AGVAnimation = (e, item, type, newLocation = 0, time = 2000) => { + if (agvData[groupEnum[e]] && AGVanimationLine[e].length < 10) { + AGVanimationLine[e].push(() => AGVAnimationF(item, type, newLocation, time)) + } } + setInterval(() => { - if (agvData.floor5BFAGVGroup) { - } -}, 1000) -setTimeout(() =>{ - setInterval(() => { - let num1 = Math.random() - // let num1 = 0.6 - // let num1 = 0.4 - if (num1 > 0.5) { + if (isLoading) { + let num1_1 = Math.random() + let num1_2 = Math.random() + let num1_3 = Math.random() + let num1_4 = Math.random() + let num1_5 = Math.random() + + if (num1_1 > 0.5) { let num2 = Math.random() * 100 - AGVAnimation('5BFAGV', 'x', num2) + AGVAnimation('2AGV', '2AGV', 'x', num2) } else { let num2 = Math.random() * 100 - AGVAnimation('5BFAGV', 'z', num2) + AGVAnimation('2AGV', '2AGV', 'z', num2) } - }, 1000) - setInterval(() => { - let num1 = Math.random() - // let num1 = 0.6 - // let num1 = 0.4 - if (num1 > 0.5) { + if (num1_2 > 0.5) { let num2 = Math.random() * 100 - AGVAnimation('3AGV', 'x', num2) + AGVAnimation('3AGV', '3AGV', 'x', num2) } else { let num2 = Math.random() * 100 - AGVAnimation('3AGV', 'z', num2) + AGVAnimation('3AGV', '3AGV', 'z', num2) } - }, 1000) - setInterval(() => { - let num1 = Math.random() - // let num1 = 0.6 - // let num1 = 0.4 - if (num1 > 0.5) { + + if (num1_3 > 0.5) { let num2 = Math.random() * 100 - AGVAnimation('2AGV', 'x', num2) + AGVAnimation('5CCAGV', '5CCAGV', 'x', num2) } else { let num2 = Math.random() * 100 - AGVAnimation('2AGV', 'z', num2) + AGVAnimation('5CCAGV', '5CCAGV', 'z', num2) } - }, 1000) - setInterval(() => { - let num1 = Math.random() - // let num1 = 0.6 - // let num1 = 0.4 - if (num1 > 0.5) { + + if (num1_4 > 0.5) { let num2 = Math.random() * 100 - AGVAnimation('5CCAGV', 'x', num2) + AGVAnimation('5BFAGV', '5BFAGV', 'x', num2) } else { let num2 = Math.random() * 100 - AGVAnimation('5CCAGV', 'z', num2) + AGVAnimation('5BFAGV', '5BFAGV', 'z', num2) } - }, 1000) -},200000000) - - -setTimeout(() =>{ - setInterval(() => { - let num1 = Math.random() - // let num1 = 0.6 - // let num1 = 0.4 - if (num1 > 0.5) { + if (num1_5 > 0.5) { let num2 = Math.random() * 100 - AGVAnimation('5CTU', 'x', num2) + AGVAnimation('5CTU', '5CTU', 'x', num2) } else { let num2 = Math.random() * 100 - AGVAnimation('5CTU', 'z', num2) + AGVAnimation('5CTU', '5CTU', 'z', num2) } - }, 1000) -},20000000) + } +}, 1000) export { agvData, diff --git a/hw-ui/src/views/board/model/animation.js b/hw-ui/src/views/board/model/animation.js index 850c77e5..ce82986e 100644 --- a/hw-ui/src/views/board/model/animation.js +++ b/hw-ui/src/views/board/model/animation.js @@ -1,11 +1,16 @@ import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' import { - tuopanInishengji, + isLoading, tuopanLocation, - tishengjiLocation + tishengjiLocation, keyidongModel, storeyHeight, tuopanModel, animationLine, storeyWidth } from './setThree' +import * as TWEEN from '@tweenjs/tween.js' +import { agvData } from '@/views/board/model/agv' + +let tuopanInishengji = true +let s = 1 const tishengjiAnimation = (model, floor, newLocation = 0, time = 2000) => { @@ -15,25 +20,37 @@ const tishengjiAnimation = (model, floor, newLocation = 0, time = 2000) => { resolve() } let distance = newLocation - tishengjiLocation.y - let time1 = setInterval(() => { - if ((distance > 0 && model.position.y >= newLocation) || (distance < 0 && model.position.y <= newLocation)) { + + let tween = new TWEEN.Tween(model.position) + .to({ y: newLocation }, Math.abs(distance) / s * 16) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { model.position.y = newLocation tishengjiLocation.y = newLocation resolve() - clearInterval(time1) - clearTimeout(time3) - } else { - model.position.y += distance / (time / 16) - tishengjiLocation.y = model.position.y - } - }, 16) - let time3 = setTimeout(() => { - model.position.y = newLocation - tishengjiLocation.y = newLocation - resolve() - clearInterval(time1) - clearTimeout(time3) - }, time + 1000) + tween.stop() + tween = null + }) + .start() + + // let time1 = setInterval(() => { + // if ((distance > 0 && model.position.y >= newLocation) || (distance < 0 && model.position.y <= newLocation)) { + // model.position.y = newLocation + // tishengjiLocation.y = newLocation + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // } else { + // model.position.y += distance / (s / 16) + // tishengjiLocation.y = model.position.y + // } + // }, 16) + // let time3 = setTimeout(() => { + // model.position.y = newLocation + // tishengjiLocation.y = newLocation + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // }, time + 1000) }) } @@ -44,26 +61,38 @@ const tuopanXAnimation = (model, newLocation = 0, time = 2000) => { resolve() } else { tuopanInishengji = newLocation === 0 + let distance = newLocation - tuopanLocation.x - let time1 = setInterval(() => { - if ((distance > 0 && model.position.x >= newLocation) || (distance < 0 && model.position.x <= newLocation)) { + let tween = new TWEEN.Tween(model.position) + .to({ x: newLocation }, Math.abs(distance) / s * 16) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { model.position.x = newLocation tuopanLocation.x = newLocation resolve() - clearInterval(time1) - clearTimeout(time3) - } else { - model.position.x += distance / (time / 16) - tuopanLocation.x = model.position.x - } - }, 16) - let time3 = setTimeout(() => { - model.position.x = newLocation - tuopanLocation.x = newLocation - resolve(0) - clearInterval(time1) - clearTimeout(time3) - }, time + 1000) + tween.stop() + tween = null + }) + .start() + + // let time1 = setInterval(() => { + // if ((distance > 0 && model.position.x >= newLocation) || (distance < 0 && model.position.x <= newLocation)) { + // model.position.x = newLocation + // tuopanLocation.x = newLocation + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // } else { + // model.position.x += distance / (time / 16) + // tuopanLocation.x = model.position.x + // } + // }, 16) + // let time3 = setTimeout(() => { + // model.position.x = newLocation + // tuopanLocation.x = newLocation + // resolve(0) + // clearInterval(time1) + // clearTimeout(time3) + // }, time + 1000) } }) } @@ -75,25 +104,36 @@ const tuopanYAnimation = (model, floor, newLocation = 0, time = 2000) => { resolve() } let distance = newLocation - tuopanLocation.y - let time1 = setInterval(() => { - if ((distance > 0 && model.position.y >= newLocation) || (distance < 0 && model.position.y <= newLocation)) { + let tween = new TWEEN.Tween(model.position) + .to({ y: newLocation }, Math.abs(distance) / s * 16) // 移动到(1, 1, 1),持续1000毫秒 + .onComplete(() => { model.position.y = newLocation tuopanLocation.y = newLocation resolve() - clearInterval(time1) - clearTimeout(time3) - } else { - model.position.y += distance / (time / 16) - tuopanLocation.y = model.position.y - } - }, 16) - let time3 = setTimeout(() => { - model.position.y = newLocation - tuopanLocation.y = newLocation - resolve() - clearInterval(time1) - clearTimeout(time3) - }, time + 1000) + tween.stop() + tween = null + }) + .start() + + // let time1 = setInterval(() => { + // if ((distance > 0 && model.position.y >= newLocation) || (distance < 0 && model.position.y <= newLocation)) { + // model.position.y = newLocation + // tuopanLocation.y = newLocation + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // } else { + // model.position.y += distance / (time / 16) + // tuopanLocation.y = model.position.y + // } + // }, 16) + // let time3 = setTimeout(() => { + // model.position.y = newLocation + // tuopanLocation.y = newLocation + // resolve() + // clearInterval(time1) + // clearTimeout(time3) + // }, time + 1000) }) } @@ -130,7 +170,30 @@ const addtuopan = (params) => { } +setInterval(() => { + if (isLoading) { + + if (animationLine.length < 5) { + + let floor = Math.ceil(Math.random() * 5) + + animationLine.push(() => { + if (tuopanInishengji) { + return Promise.all([tishengjiAnimation(keyidongModel, floor, storeyHeight[floor]), tuopanYAnimation(tuopanModel, floor, storeyHeight[floor])]) + } else { + animationLine.push(() => tishengjiAnimation(keyidongModel, floor, storeyHeight[floor])) + } + }) + if (Math.random() > 0.5) { + animationLine.push(() => tuopanXAnimation(tuopanModel, storeyWidth[floor])) + animationLine.push(() => tuopanXAnimation(tuopanModel, 0)) + } + } + } +}, 1800) + export { + tuopanInishengji, tishengjiAnimation, tuopanXAnimation, tuopanYAnimation, diff --git a/hw-ui/src/views/board/model/index.vue b/hw-ui/src/views/board/model/index.vue index 3081b75d..266c17d9 100644 --- a/hw-ui/src/views/board/model/index.vue +++ b/hw-ui/src/views/board/model/index.vue @@ -94,6 +94,7 @@ import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRe import Demo from '@/components/model/demo.vue' import { + tuopanInishengji, tishengjiAnimation, tuopanXAnimation, tuopanYAnimation, @@ -109,7 +110,6 @@ import { loadF, storeyHeight, storeyWidth, - tuopanInishengji, tuopanLocation, animationLine } from './setThree' @@ -125,7 +125,7 @@ export default { data() { return { num: -60, - num1: 10, + num1: 90, floor: 1, tuopanFloor: 1, fx:'', @@ -139,8 +139,9 @@ export default { // controls.enableZoom = false // loadF([ 'tishengji_tuopan']) - // loadF(['tishengji', 'AGVchongdianzhuang002', 'AGVchongdianzhuang003', 'changfang002', 'changfang003', 'quanzidongchaibaojizhaungpeixian003', 'tishengji_keyidongbufen', 'tishengji_tuopan', 'AGVchongdianzhuang005', 'changfang005', 'liku005']) - loadF(['changfang002', 'changfang003', 'changfang005']) + loadF(['tishengji', 'AGVchongdianzhuang002', 'AGVchongdianzhuang003', 'changfang002', 'changfang003', 'quanzidongchaibaojizhaungpeixian003', 'tishengji_keyidongbufen', 'tishengji_tuopan', 'AGVchongdianzhuang005', 'changfang005', 'liku005']) + // loadF(['changfang002', 'changfang003', 'changfang005']) + // 创建CSS2DObject // const label = this.$refs.demo @@ -150,9 +151,6 @@ export default { // 渲染循环 - setInterval(() => { - - }, 1000 * 10) }, methods: { @@ -192,7 +190,7 @@ export default { }, agvAn() { this.rotate -=this.num1 - AGVAnimation('5BFAGV','rotate',this.rotate,) + AGVAnimation('3AGV','rotate',this.rotate,) } } } diff --git a/hw-ui/src/views/board/model/setThree.js b/hw-ui/src/views/board/model/setThree.js index 3b4c8516..415c3bd3 100644 --- a/hw-ui/src/views/board/model/setThree.js +++ b/hw-ui/src/views/board/model/setThree.js @@ -5,6 +5,7 @@ import * as TWEEN from '@tweenjs/tween.js' import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' +let isLoading = false let isAnimation = false let animationLine = [] let keyidongModel @@ -105,7 +106,6 @@ const animation = async() => { function animate() { if (animationLine.length > 0 && isAnimation === false) { - console.log('动画') isAnimation = true animation(animationLine) } @@ -119,13 +119,17 @@ animate() let a = 0 +const loadingManager = new THREE.LoadingManager(); +loadingManager.onLoad = function() { + isLoading = true +}; const loadF = (e) => { e.forEach(v => { let mtlLoader = new MTLLoader() mtlLoader.load(`/model/${v}/${v}.mtl`, materials => { materials.preload() - let loader = new OBJLoader() + let loader = new OBJLoader(loadingManager) loader.setMaterials(materials) loader.load( `/model/${v}/${v}.obj`, @@ -152,7 +156,6 @@ const loadF = (e) => { }) } -let tuopanInishengji = true let storeyHeight = { 1: 0, 2: 261.9, @@ -181,6 +184,7 @@ let tuopanLocation = { } export { + isLoading, keyidongModel, tuopanModel, scene, @@ -189,7 +193,6 @@ export { loadF, animationLine, labelRenderer, - tuopanInishengji, storeyHeight, storeyWidth, tuopanLocation, diff --git a/hw-ui/src/views/mes/productOrder/addProductOrder.vue b/hw-ui/src/views/mes/productOrder/addProductOrder.vue index 6c4d6e1f..461dc37b 100644 --- a/hw-ui/src/views/mes/productOrder/addProductOrder.vue +++ b/hw-ui/src/views/mes/productOrder/addProductOrder.vue @@ -27,6 +27,16 @@ /> + + + + + 搜索 重置 @@ -52,9 +62,9 @@ - + @@ -130,12 +140,8 @@