Merge remote-tracking branch 'origin/master'

master
xs 6 months ago
commit 6dd27687ca

@ -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<MesProductOrder> 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<MesProductOrder> productOrderList) {
int result = 0;
for (MesProductOrder productOrder : productOrderList) {
productOrder.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
result = mesProductOrderService.updateMesProductOrder(productOrder);
}
return toAjax(result);
}
/**
*
*/

@ -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;
}

@ -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<MesProductOrder> selectMesProductOrderListByPreOrderId(Long productOrderId);
}

@ -87,4 +87,12 @@ public interface IMesProductOrderService
* @return
*/
public Boolean verifyBOMIsProduction(Long materialBomId);
/**
*
*
* @param mesProductOrder
* @return
*/
public List<MesProductOrder> selectAllListTaskList(MesProductOrder mesProductOrder);
}

@ -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<MesProductOrder> selectAllListTaskList(MesProductOrder mesProductOrder) {
Long productOrderId = mesProductOrder.getProductOrderId();
// 结果列表,用于存储所有关联的订单
List<MesProductOrder> result = new ArrayList<>();
// 记录已经访问过的订单ID防止重复访问
Set<Long> 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<MesProductOrder> result, MesProductOrder currentOrder, Set<Long> visited) {
if (currentOrder == null || visited.contains(currentOrder.getProductOrderId())) {
return;
}
// 将当前订单添加到结果列表
result.add(currentOrder);
// 将当前订单的ID添加到访问集合中
visited.add(currentOrder.getProductOrderId());
// 获取所有以当前订单为父级ID的子订单列表
List<MesProductOrder> children = mesProductOrderMapper.selectMesProductOrderListByPreOrderId(currentOrder.getProductOrderId());
for (MesProductOrder child : children) {
// 递归遍历每个子订单
traverseChildren(result, child, visited);
}
}
}

@ -39,6 +39,7 @@
<result property="materialName" column="material_name"/>
<result property="materialBomDesc" column="material_bom_desc"/>
<result property="productionTime" column="production_time"/>
<result property="preOrderId" column="pre_order_id"/>
</resultMap>
<sql id="selectMesProductOrderVo">
@ -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 @@
<if test="orderStatus != null and orderStatus != ''">and mpo.order_status = #{orderStatus}</if>
<if test="stockLockFlag != null and stockLockFlag != ''">and mpo.stock_lock_flag = #{stockLockFlag}</if>
<if test="saleOrderFlag != null and saleOrderFlag != ''">and mpo.sale_order_flag = #{saleOrderFlag}</if>
<if test="preOrderId != null and preOrderId != ''">and mpo.pre_order_id = #{preOrderId}</if>
<if test="createBy != null and createBy != ''">and mpo.create_by = #{createBy}</if>
<if test="createTime != null ">and mpo.create_time = #{createTime}</if>
<if test="updateBy != null and updateBy != ''">and mpo.update_by = #{updateBy}</if>
@ -160,6 +163,7 @@
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="planDeliveryDate != null">plan_delivery_date,</if>
<if test="preOrderId != null">pre_order_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderCode != null and orderCode != ''">#{orderCode},</if>
@ -190,6 +194,7 @@
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="planDeliveryDate != null">#{planDeliveryDate},</if>
<if test="preOrderId != null">#{preOrderId},</if>
</trim>
</insert>
@ -224,6 +229,7 @@
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="planDeliveryDate != null">plan_delivery_date = #{planDeliveryDate},</if>
<if test="preOrderId != null">pre_order_id = #{preOrderId},</if>
</trim>
where product_order_id = #{productOrderId}
</update>
@ -258,4 +264,9 @@
limit 1
</select>
<select id="selectMesProductOrderListByPreOrderId" parameterType="Long" resultMap="MesProductOrderResult">
<include refid="selectMesProductOrderVo"/>
where mpo.pre_order_id = #{productOrderId}
</select>
</mapper>

2
hw-ui/.gitignore vendored

@ -22,4 +22,4 @@ selenium-debug.log
package-lock.json
yarn.lock
vue.config.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
})
}

@ -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",

@ -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,

@ -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,

@ -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,)
}
}
}

@ -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,

@ -27,6 +27,16 @@
/>
</el-select>
</el-form-item>
<el-form-item label="工艺路线" prop="dispatchId">
<el-select v-model="form.dispatchId" filterable placeholder="请选择工艺路线" clearable>
<el-option
v-for="item in routeList"
:key="item.routeId"
:label="item.routeName"
:value="item.routeId"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
@ -52,9 +62,9 @@
</template>
</el-table-column>
<el-table-column label="工艺路线" align="center" prop="dispatchName" v-if="columns[9].visible" width="120"/>
<el-table-column label="单位时间" align="center" prop="productionTime" v-if="columns[27].visible">
<el-table-column label="单位时间" align="center" prop="productionTime" v-if="columns[27].visible">
<template slot-scope="scope">
<span>{{formatDayHourMinutes(scope.row.productionTime) }}</span>
<span>{{ formatDayHourMinutes(scope.row.productionTime) }}</span>
</template>
</el-table-column>
<el-table-column label="销售数量" align="center" prop="saleAmount" v-if="columns[10].visible"/>
@ -130,12 +140,8 @@
<script>
import {
listProductOrder,
getProductOrder,
delProductOrder,
addProductOrder,
updateProductOrder,
getOrderCode, productOrderLockInventory, productOrderPublish, productOrderRecall
} from "@/api/mes/productOrder";
import {findRouteList} from "@/api/mes/baseRoute";
export default {
name: "ProductOrder",

@ -202,6 +202,13 @@
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="handleProductionScheduling(scope.row)"
v-hasPermi="['mes:productOrder:edit']"
>排产
</el-button>
<el-button
size="mini"
type="text"
@ -338,6 +345,11 @@
placeholder="请选择计划交货日期">
</el-date-picker>
</el-form-item>
<el-form-item label="前置生产工单" prop="preOrderCode">
<el-input v-model="form.preOrderCode" placeholder="请点击右侧检索生产工单" :disabled="productOrderDisabled" readonly>
<el-button slot="append" icon="el-icon-search" @click="handleProductOrderAdd"></el-button>
</el-input>
</el-form-item>
<el-form-item label="计划开始时间" prop="planBeginTime">
<el-date-picker clearable
v-model="form.planBeginTime"
@ -416,6 +428,11 @@
placeholder="请选择计划交货日期">
</el-date-picker>
</el-form-item>
<el-form-item label="前置生产工单" prop="preOrderCode">
<el-input v-model="form.preOrderCode" placeholder="请点击右侧检索生产工单" :disabled="productOrderDisabled" readonly>
<el-button slot="append" icon="el-icon-search" @click="handleProductOrderAdd"></el-button>
</el-input>
</el-form-item>
<el-form-item label="计划开始时间" prop="planBeginTime">
<el-date-picker clearable
v-model="form.planBeginTime"
@ -460,6 +477,15 @@
</div>
</el-dialog>
<!-- 添加生产工单信息对话框 -->
<el-dialog title="选择生产工单信息" :visible.sync="productOrderOpen" width="1000px" append-to-body>
<add-product-order @selection="handleSelection" ref="productOrderRef"></add-product-order>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitProductOrderForm"> </el-button>
<el-button @click="productOrderOpen = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
@ -476,14 +502,17 @@ import addSaleOrder from '@//views/mes/productOrder/addSaleOrder.vue';
import {getMaterialVisionList} from "@//api/mes/materialBom";
import {findRouteList} from "@//api/mes/baseRoute";
import addBom from '@//views/mes/materialBom/addBom.vue';
import add_ProductOrder from '@//views/mes/productOrder/addProductOrder.vue';
import router from "@//router";
import {parseTime} from "@/utils/ruoyi";
export default {
name: "ProductOrder",
dicts: ['active_flag', 'plan_status', 'dispatch_type', 'mes_sale_type'],
components: {
'add-SaleOrder': addSaleOrder,
'add-bom': addBom
'add-bom': addBom,
'add-product-order': add_ProductOrder,
},
data() {
return {
@ -513,6 +542,8 @@ export default {
noOrderOpen: false,
//
materialOpen: false,
//
productOrderOpen: false,
//
queryParams: {
pageNum: 1,
@ -630,9 +661,9 @@ export default {
materialBomList: [],
//线
routeList: [],
saleOrderDisabled: true,
materialDisabled: true,
productOrderDisabled: true,
//
MES_SALE_TYPE: {
MES_SALE_TYPE_EXTERNAL: '1',//
@ -783,6 +814,19 @@ export default {
this.saleOrderOpen = false;
},
/** 提交生产工单信息按钮 */
submitProductOrderForm() {
let selectedRow = this.$refs.productOrderRef.selectedRow;
this.form.preOrderId = selectedRow.saleOrderId;
this.form.preOrderCode = selectedRow.orderCode;
if (selectedRow.planBeginTime != null && this.form.planBeginTime == null){
const date = new Date(selectedRow.planBeginTime);
date.setDate(date.getDate() + 1)
this.form.planBeginTime = parseTime(date, '{y}-{m}-{d} {h}:{i}:{s}');
}
this.productOrderOpen = false;
},
changeSaleType(value) {
this.form.saleOrderId = null;
this.form.saleorderCode = null;
@ -837,6 +881,11 @@ export default {
}
},
/** 新增按钮操作 */
handleProductOrderAdd() {
this.productOrderOpen = true;
},
/** 无订单新增按钮操作 */
handleNoOrderAdd() {
this.materialDisabled = false;
@ -922,7 +971,14 @@ export default {
this.$tab.closeOpenPage(router.currentRoute);
this.$tab.openPage("工单[" + orderCode + "]生产派工", '/mes/product-plan/index/' + productOrderId, params);
},
/** 排产 */
handleProductionScheduling(row) {
const productOrderId = row.productOrderId;
const orderCode = row.orderCode;
const params = {queryParams: this.queryParams};
this.$tab.closeOpenPage(router.currentRoute);
this.$tab.openPage("工单[" + orderCode + "]排产", '/mes/production-scheduling/index/' + productOrderId, params);
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {

@ -0,0 +1,598 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="工单编号" prop="orderCode">
<el-input
v-model="queryParams.orderCode"
placeholder="请输入工单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="销售订单编号" prop="saleorderCode">
<el-input
v-model="queryParams.saleorderCode"
placeholder="请输入销售订单编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleSave"
>保存
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-sort"
size="mini"
@click="toggleExpandAll"
>展开/折叠
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-back"
size="mini"
@click="close"
>关闭
</el-button>
</el-col>
<el-col :span="1.5">
<el-radio-group v-model="arrangeType">
<el-radio
v-for="dict in arrangeTypeList"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
v-if="refreshTable"
v-loading="loading"
:data="productOrderList"
row-key="productOrderId"
:default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column label="工单编号" prop="orderCode" v-if="columns[1].visible" width="250"/>
<el-table-column label="销售订单ID" align="center" prop="saleOrderId" v-if="columns[2].visible" width="100"/>
<el-table-column label="销售订单标识" align="center" prop="saleOrderFlag" v-if="columns[3].visible" width="100"/>
<el-table-column label="销售订单编号" align="center" prop="saleorderCode" v-if="columns[4].visible" width="120"/>
<el-table-column label="销售订单行号" align="center" prop="saleorderLinenumber" v-if="columns[5].visible" width="100"/>
<el-table-column label="项目编号" align="center" prop="projectNo" v-if="columns[6].visible" width="100"/>
<el-table-column label="销售类型" align="center" prop="saleType" v-if="columns[7].visible">
<template slot-scope="scope">
<dict-tag :options="dict.type.mes_sale_type" :value="scope.row.saleType"/>
</template>
</el-table-column>
<el-table-column label="物料ID" align="center" prop="materialId" v-if="columns[8].visible"/>
<el-table-column label="物料bomID" align="center" prop="materialBomId" v-if="columns[9].visible"/>
<el-table-column label="派工类型" align="center" prop="dispatchType" v-if="columns[10].visible">
<template slot-scope="scope">
<dict-tag :options="dict.type.dispatch_type" :value="scope.row.dispatchType"/>
</template>
</el-table-column>
<el-table-column label="派工ID" align="center" prop="dispatchId" v-if="columns[11].visible"/>
<el-table-column label="销售数量" align="center" prop="saleAmount" v-if="columns[12].visible"/>
<el-table-column label="计划数量" align="center" prop="planAmount" v-if="columns[14].visible"/>
<el-table-column label="已派工数量" align="center" prop="dispatchAmount" width="90" v-if="columns[15].visible"/>
<el-table-column label="完成数量" align="center" prop="completeAmount" v-if="columns[16].visible"/>
<el-table-column label="计划交货日期" align="center" prop="planDeliveryDate" width="180" v-if="columns[13].visible">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.planDeliveryDate, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="发布时间" align="center" prop="releaseTime" width="180" v-if="columns[17].visible">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.releaseTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="工期(天)" align="center" prop="duration" width="90" v-if="columns[30].visible"/>
<el-table-column label="计划开始时间" align="center" prop="planBeginTime" width="230" v-if="columns[18].visible">
<template slot-scope="scope">
<el-date-picker v-model="scope.row.planBeginTime" style="width:200px;"
placeholder="请选择计划开始时间"
type="datetime" value-format="yyyy-MM-dd HH:mm:ss" clearable
/>
</template>
</el-table-column>
<el-table-column label="计划结束时间" align="center" prop="planEndTime" width="230" v-if="columns[19].visible">
<template slot-scope="scope">
<el-date-picker v-model="scope.row.planEndTime" style="width:200px;"
placeholder="请选择计划完成时间"
type="datetime" value-format="yyyy-MM-dd HH:mm:ss" clearable
/>
</template>
</el-table-column>
<el-table-column label="开始时间" align="center" prop="realBeginTime" width="180" v-if="columns[20].visible">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.realBeginTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="完成时间" align="center" prop="realEndTime" width="180" v-if="columns[21].visible">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.realEndTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="工单状态" align="center" prop="orderStatus" v-if="columns[22].visible"/>
<el-table-column label="库存锁定标识" align="center" prop="stockLockFlag" v-if="columns[23].visible"/>
<el-table-column label="备注" align="center" prop="remark" v-if="columns[24].visible"/>
<el-table-column label="前置生产工单ID" align="center" prop="preOrderId" v-if="columns[29].visible"/>
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">-->
<!-- <template slot-scope="scope">-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['mes:productOrder:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-plus"-->
<!-- @click="handleAdd(scope.row)"-->
<!-- v-hasPermi="['mes:productOrder:add']"-->
<!-- >新增</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['mes:productOrder:remove']"-->
<!-- >删除</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!-- 添加或修改生产工单;生产工单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="工单编号" prop="orderCode">
<el-input v-model="form.orderCode" placeholder="请输入工单编号"/>
</el-form-item>
<el-form-item label="销售订单ID" prop="saleOrderId">
<el-input v-model="form.saleOrderId" placeholder="请输入销售订单ID"/>
</el-form-item>
<el-form-item label="销售订单标识" prop="saleOrderFlag">
<el-input v-model="form.saleOrderFlag" placeholder="请输入销售订单标识"/>
</el-form-item>
<el-form-item label="销售订单编号" prop="saleorderCode">
<el-input v-model="form.saleorderCode" placeholder="请输入销售订单编号"/>
</el-form-item>
<el-form-item label="销售订单行号" prop="saleorderLinenumber">
<el-input v-model="form.saleorderLinenumber" placeholder="请输入销售订单行号"/>
</el-form-item>
<el-form-item label="项目编号" prop="projectNo">
<el-input v-model="form.projectNo" placeholder="请输入项目编号"/>
</el-form-item>
<el-form-item label="物料ID" prop="materialId">
<el-input v-model="form.materialId" placeholder="请输入物料ID"/>
</el-form-item>
<el-form-item label="物料bomID" prop="materialBomId">
<el-input v-model="form.materialBomId" placeholder="请输入物料bomID"/>
</el-form-item>
<el-form-item label="派工ID" prop="dispatchId">
<el-input v-model="form.dispatchId" placeholder="请输入派工ID"/>
</el-form-item>
<el-form-item label="销售数量" prop="saleAmount">
<el-input v-model="form.saleAmount" placeholder="请输入销售数量"/>
</el-form-item>
<el-form-item label="计划交货日期" prop="planDeliveryDate">
<el-date-picker clearable
v-model="form.planDeliveryDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择计划交货日期">
</el-date-picker>
</el-form-item>
<el-form-item label="计划数量" prop="planAmount">
<el-input v-model="form.planAmount" placeholder="请输入计划数量"/>
</el-form-item>
<el-form-item label="已派工数量" prop="dispatchAmount">
<el-input v-model="form.dispatchAmount" placeholder="请输入已派工数量"/>
</el-form-item>
<el-form-item label="完成数量" prop="completeAmount">
<el-input v-model="form.completeAmount" placeholder="请输入完成数量"/>
</el-form-item>
<el-form-item label="发布时间" prop="releaseTime">
<el-date-picker clearable
v-model="form.releaseTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择发布时间">
</el-date-picker>
</el-form-item>
<el-form-item label="计划开始时间" prop="planBeginTime">
<el-date-picker clearable
v-model="form.planBeginTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择计划开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="计划结束时间" prop="planEndTime">
<el-date-picker clearable
v-model="form.planEndTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择计划结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="开始时间" prop="realBeginTime">
<el-date-picker clearable
v-model="form.realBeginTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="完成时间" prop="realEndTime">
<el-date-picker clearable
v-model="form.realEndTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择完成时间">
</el-date-picker>
</el-form-item>
<el-form-item label="库存锁定标识" prop="stockLockFlag">
<el-input v-model="form.stockLockFlag" placeholder="请输入库存锁定标识"/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
</el-form-item>
<el-form-item label="前置生产工单ID" prop="preOrderId">
<treeselect v-model="form.preOrderId" :options="productOrderOptions" :normalizer="normalizer"
placeholder="请选择前置生产工单ID"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
allListProductOrder,
getProductOrder,
delProductOrder,
addProductOrder,
updateProductOrder, batchEditingProductOrder
} from "@/api/mes/productOrder";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {parseTime} from "@/utils/ruoyi";
export default {
name: "ProductionScheduling",
dicts: ['active_flag', 'plan_status', 'dispatch_type', 'mes_sale_type'],
components: {
Treeselect
},
data() {
return {
//
loading: true,
//
showSearch: true,
// ;
productOrderList: [],
// ;
productOrderOptions: [],
//
title: "",
//
open: false,
//
isExpandAll: true,
//
refreshTable: true,
//
queryParams: {
orderCode: null,
saleOrderId: null,
saleOrderFlag: null,
saleorderCode: null,
saleorderLinenumber: null,
projectNo: null,
saleType: null,
materialId: null,
materialBomId: null,
dispatchType: null,
dispatchId: null,
saleAmount: null,
planDeliveryDate: null,
planAmount: null,
dispatchAmount: null,
completeAmount: null,
releaseTime: null,
planBeginTime: null,
planEndTime: null,
realBeginTime: null,
realEndTime: null,
orderStatus: null,
stockLockFlag: null,
preOrderId: null
},
//
form: {},
arrangeType: 1,
arrangeTypeList: [
{label: '手动安排', value: 0},
{label: '自动安排', value: 1}
],
//
rules: {
orderCode: [
{required: true, message: "工单编号不能为空", trigger: "blur"}
],
saleOrderFlag: [
{required: true, message: "销售订单标识不能为空", trigger: "blur"}
],
saleType: [
{required: true, message: "销售类型不能为空", trigger: "change"}
],
},
columns: [
{key: 0, label: `主键标识`, visible: false},
{key: 1, label: `工单编号`, visible: true},
{key: 2, label: `销售订单ID`, visible: false},
{key: 3, label: `销售订单标识`, visible: false},
{key: 4, label: `销售订单编号`, visible: true},
{key: 5, label: `销售订单行号`, visible: false},
{key: 6, label: `项目编号`, visible: false},
{key: 7, label: `销售类型`, visible: true},
{key: 8, label: `物料ID`, visible: false},
{key: 9, label: `物料bomID`, visible: false},
{key: 10, label: `派工类型`, visible: false},
{key: 11, label: `派工ID`, visible: false},
{key: 12, label: `销售数量`, visible: true},
{key: 13, label: `计划交货日期`, visible: false},
{key: 14, label: `计划数量`, visible: true},
{key: 15, label: `已派工数量`, visible: true},
{key: 16, label: `完成数量`, visible: true},
{key: 17, label: `发布时间`, visible: false},
{key: 18, label: `计划开始时间`, visible: true},
{key: 19, label: `计划结束时间`, visible: true},
{key: 20, label: `开始时间`, visible: false},
{key: 21, label: `完成时间`, visible: false},
{key: 22, label: `工单状态`, visible: false},
{key: 23, label: `库存锁定标识`, visible: false},
{key: 24, label: `备注`, visible: false},
{key: 25, label: `创建人`, visible: false},
{key: 26, label: `创建时间`, visible: false},
{key: 27, label: `更新人`, visible: false},
{key: 28, label: `更新时间`, visible: false},
{key: 29, label: `前置生产工单ID`, visible: false},
{key: 30, label: `工期(天)`, visible: true},
],
};
},
created() {
const productOrderId = this.$route.params && this.$route.params.productOrderId;
if (productOrderId != null) {
this.queryParams.productOrderId = productOrderId;
}
this.getList();
},
watch: {
productOrderList: {
handler(newVal) {
this.filteredList = this.extractFields(newVal);
},
deep: true,
immediate: true
}
},
methods: {
/** 查询生产工单;生产工单列表 */
getList() {
this.loading = true;
allListProductOrder(this.queryParams).then(response => {
this.productOrderList = this.handleTree(response.data, "productOrderId", "preOrderId");
this.loading = false;
});
},
/** 转换生产工单;生产工单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.productOrderId,
label: node.orderCode,
children: node.children
};
},
/** 查询生产工单;生产工单下拉树结构 */
getTreeselect() {
allListProductOrder().then(response => {
this.productOrderOptions = [];
const data = {productOrderId: 0, orderCode: '顶级节点', children: []};
data.children = this.handleTree(response.data, "productOrderId", "preOrderId");
this.productOrderOptions.push(data);
});
},
//
cancel() {
this.open = false;
this.reset();
},
/** 关闭按钮 */
close() {
const obj = {path: "/mes/plan/productOrder", query: {t: Date.now(), queryParams: this.$route.query.queryParams}};
this.$tab.closeOpenPage(obj);
},
//
reset() {
this.form = {
productOrderId: null,
orderCode: null,
saleOrderId: null,
saleOrderFlag: null,
saleorderCode: null,
saleorderLinenumber: null,
projectNo: null,
saleType: null,
materialId: null,
materialBomId: null,
dispatchType: null,
dispatchId: null,
saleAmount: null,
planDeliveryDate: null,
planAmount: null,
dispatchAmount: null,
completeAmount: null,
releaseTime: null,
planBeginTime: null,
planEndTime: null,
realBeginTime: null,
realEndTime: null,
orderStatus: null,
stockLockFlag: null,
remark: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
preOrderId: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd(row) {
this.reset();
this.getTreeselect();
if (row != null && row.productOrderId) {
this.form.preOrderId = row.productOrderId;
} else {
this.form.preOrderId = 0;
}
this.open = true;
this.title = "添加生产工单";
},
/** 保存按钮操作 */
handleSave() {
const extractedData = this.extractFields(this.productOrderList);
batchEditingProductOrder(extractedData).then(response => {
this.$modal.msgSuccess("批量保存成功");
this.getList();
});
},
extractFields(data) {
let result = [];
data.forEach(item => {
const {productOrderId, planBeginTime, planEndTime, children} = item;
result.push({productOrderId, planBeginTime, planEndTime});
if (planBeginTime != null && planEndTime != null) {
item.duration = this.calculateDaysDifference(planBeginTime, planEndTime);
}
if (this.arrangeType === 1 && planEndTime != null && children != null) {
const date = new Date(planEndTime);
date.setDate(date.getDate() + 1);
children.forEach(item => {
item.planBeginTime = parseTime(date);
})
}
if (children) {
result = result.concat(this.extractFields(children));
}
});
return result;
},
//
calculateDaysDifference(date1, date2) {
//
const dateObj1 = new Date(date1);
const dateObj2 = new Date(date2);
//
const timeDifference = dateObj2 - dateObj1;
return (timeDifference / (1000 * 60 * 60 * 24)).toFixed(2);
},
/** 展开/折叠操作 */
toggleExpandAll() {
this.refreshTable = false;
this.isExpandAll = !this.isExpandAll;
this.$nextTick(() => {
this.refreshTable = true;
});
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getTreeselect();
if (row != null) {
this.form.preOrderId = row.productOrderId;
}
getProductOrder(row.productOrderId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改生产工单";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.productOrderId != null) {
updateProductOrder(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addProductOrder(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除生产工单;生产工单编号为"' + row.productOrderId + '"的数据项?').then(function () {
return delProductOrder(row.productOrderId);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
}
}
};
</script>
Loading…
Cancel
Save