1270 lines
38 KiB
Vue
1270 lines
38 KiB
Vue
<script lang="ts" setup>
|
||
import { ref, onMounted, computed } from 'vue'
|
||
import { nextTick } from 'vue'
|
||
import BoardView from '@/components/borderView/BoardView.vue'
|
||
import {
|
||
Select, SelectOption, Pagination, TreeSelect, Form, FormItem,
|
||
Input, Button, Table, Modal, Textarea, Tooltip, Switch,
|
||
InputNumber, Checkbox
|
||
} from 'ant-design-vue'
|
||
|
||
import { Knife, SysConfig } from '@/imes/biz/SysConfig'
|
||
import { ParserMain } from '@/imes/processParser/parseMain'
|
||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||
import { getListAllSimple, getOrderSource } from '@/api/production/productManagerList'
|
||
import { BoardShowType } from '@/imes/vo/enums/BoardShowType'
|
||
|
||
import { BlockBorderPoint } from '@/imes/vo/point/BlockBorderPoint'
|
||
import { BoardEditor } from '@/imes/biz/RenderNewBoard'
|
||
import { BasicTable, TableAction, useTable } from '@/components/Table'
|
||
import { optimizeColumns1 } from '../production/productManagerList/productManagerList.data'
|
||
import { DataHandleServe } from '@/imes/dataHandle/DataHandleServe'
|
||
import { convertData } from '@/imes/common/transform'
|
||
import { blockborderClass } from '@/imes/dataClass/blockborderClass'
|
||
import { Arc2d, Curve2d } from '@/imes/common/base/CAD'
|
||
import { ProcessorContext } from './dataHandle/base'
|
||
import { OptimizeLayoutProcessor } from './dataHandle/optimizeLayout/optimizeLayout'
|
||
import { ToolsHelper } from './dataHandle/tools/tool'
|
||
import {
|
||
BlockPlaceResult, BoardPlaceResult, BoardPosition, MaterialPlaceResult, PlaceBoard, PlaceStyle,
|
||
PlaceBlock, PlaceBlockDetail,
|
||
PlaceMaterial, RemainBlock,
|
||
PlacePositionClass,
|
||
CodeParams,
|
||
BlockHole,
|
||
BlockModel,
|
||
BlockModelPoint
|
||
} from './dataHandle/confClass'
|
||
import { BlockSizePlus } from './dataHandle/common/LayoutEngine/BlockSizePlus'
|
||
import { Point } from './dataHandle/common/Vector2'
|
||
import { PlacePositionHelper } from './dataHandle/common/PlacePostionHelper'
|
||
import { DisPoseModelInBoardBorder } from './dataHandle/common/LayoutEngine/DisposeModelInBoardBorder'
|
||
import { getMaterialSealEdge } from './dataHandle/common/BlockSealEdge'
|
||
import { ArrayExt } from './dataHandle/ArrayExt'
|
||
import { CutOrder } from './dataHandle/common/cutorder/CutOrder'
|
||
import { CutPointHelper } from './dataHandle/common/cutorder/CutPointHelper'
|
||
import { CodeParamsList, CodeParamsObj } from '@/imes/processParser/confClass'
|
||
import { BlockHelper } from './dataHandle/common/LayoutEngine/BlockHelper'
|
||
|
||
|
||
const selectedMachineID = ref() // 机台选中
|
||
const machineList = ref<any>([]) // 机台列表
|
||
// 1920321997498220544 1907276351086264320 1920401449485860864 1920739893772812288
|
||
const orderNo = ref('1920401449485860864')
|
||
const canvasWidth = ref(1200)
|
||
const canvasHeight = ref(650)
|
||
const paginationCurrent = ref<any>(1)
|
||
const paginationCurrentAll = ref<any>(1)
|
||
const boardEditor = ref<BoardEditor>()
|
||
const canvasMain = ref()
|
||
const canvas = ref()
|
||
const isOptimizeing = ref(false)
|
||
const _handleServe = ref<OptimizeLayoutProcessor | null>(null)
|
||
const selectVal = ref<any>()
|
||
const plateSelectOptions = ref<any>([])
|
||
const parserMain = ref<ParserMain>(new ParserMain())
|
||
const testData1 = ref('')
|
||
const dataBase = ref<any>(null)
|
||
|
||
|
||
|
||
// 添加显示标志位数组,用于记录当前需要绘制的内容
|
||
const displayFlags = ref({
|
||
isLockd: false, // 是否锁定
|
||
showBlocks: false, // 是否显示小板
|
||
showCutPoints: false, // 是否显示下刀点
|
||
showCutOrders: false, // 是否显示开料顺序
|
||
showCutNo: false, // 是否显示板号
|
||
showCutArrow: false, // 是否显示开料方向箭头
|
||
showManualPlace: false, // 是否显示手动排版
|
||
showHoles: false, // 是否显示孔洞
|
||
showModels: false, // 是否显示造型
|
||
});
|
||
|
||
// 初始化解析器
|
||
parserMain.value.setDeviceByKey('device1')
|
||
|
||
// 画布控制器
|
||
const canvasController = ref({
|
||
showType: BoardShowType.NORMAL,
|
||
showHelpCut: false,
|
||
isDragingBlock: false,
|
||
clickedBlock: new PlaceBlock(),
|
||
clickedScrapBlock: new RemainBlock(1, 1, 100, 100),
|
||
dragedDistance: Point,
|
||
beginDragPosition: Point,
|
||
mousePostion: Point,
|
||
dragingBlockPoint: BlockBorderPoint,
|
||
closestBlockPoint: BlockBorderPoint
|
||
})
|
||
|
||
const currentMaterial = computed(() => {
|
||
if (!dataBase.value?.materialList) return null;
|
||
const mIndex = dataBase.value.materialList.findIndex(e => e.goodsId === selectVal.value);
|
||
return mIndex >= 0 ? dataBase.value.materialList[mIndex] : null;
|
||
});
|
||
|
||
const currentBoard = computed(() => {
|
||
if (!currentMaterial.value?.boardList) return null;
|
||
const pIndex = paginationCurrent.value - 1;
|
||
return pIndex >= 0 && pIndex < currentMaterial.value.boardList.length
|
||
? currentMaterial.value.boardList[pIndex]
|
||
: null;
|
||
});
|
||
|
||
onMounted(() => {
|
||
getOptions();
|
||
})
|
||
|
||
const [registerTable, { setTableData, updateTableData, getDataSource }] = useTable({
|
||
title: '',
|
||
columns: optimizeColumns1,
|
||
useSearchForm: false,
|
||
rowKey: 'id',
|
||
pagination: false,
|
||
canResize: true,
|
||
maxHeight: 100,
|
||
showTableSetting: false,
|
||
actionColumn: {}
|
||
})
|
||
|
||
/**
|
||
* 获取弹出容器
|
||
*/
|
||
function getPopupContainer(node?: HTMLElement): HTMLElement {
|
||
return (node?.parentNode as HTMLElement) ?? document.body
|
||
}
|
||
|
||
/**
|
||
* 获取机台列表
|
||
*/
|
||
async function getOptions() {
|
||
const res = await getListAllSimple({ type: 1 });
|
||
if (res) {
|
||
machineList.value = res;
|
||
selectedMachineID.value = res[0].id;
|
||
_getPlaceOrderData();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 订单变化处理
|
||
*/
|
||
function orderNoChange() {
|
||
_getPlaceOrderData();
|
||
}
|
||
|
||
/**
|
||
* 机台变化处理
|
||
*/
|
||
function machineChange() {
|
||
// 机台变化逻辑
|
||
}
|
||
|
||
/**
|
||
* 获取排版订单数据
|
||
*/
|
||
async function _getPlaceOrderData() {
|
||
const params = {
|
||
// orderId: '1792854086534561792',
|
||
// machineId: '14193',
|
||
orderId: orderNo.value,
|
||
machineId: selectedMachineID.value,
|
||
};
|
||
|
||
const res = await getOrderSource(params);
|
||
if (!res) return;
|
||
|
||
let conf = JSON.parse(res.machineDTO.setting);
|
||
let tempData = { ...res, optimizeBoardModelDOS: [] };
|
||
let newGoodsList: any[] = [];
|
||
for (let material of tempData.goodsList) {
|
||
if (material.height == 0) material.height = 2440;
|
||
if (material.width == 0) material.width = 1220;
|
||
|
||
if (newGoodsList.findIndex(e => e.goodsId == material.goodsId) == -1) {
|
||
newGoodsList.push(material);
|
||
}
|
||
}
|
||
|
||
tempData.goodsList = newGoodsList;
|
||
|
||
let newTestData = convertData(tempData);
|
||
let goodsId = newTestData.materialList.map(e => e.goodsId)[0]
|
||
|
||
newTestData.blockList.forEach(block => {
|
||
block.goodsId = goodsId
|
||
});
|
||
dataBase.value = newTestData;
|
||
|
||
let sysConfig = new SysConfig(conf);
|
||
let _sysConfig = { ...sysConfig };
|
||
|
||
setTableData(newTestData.materialList);
|
||
selectVal.value = newTestData.materialList[0].goodsId;
|
||
plateSelectOptions.value = newTestData.materialList;
|
||
_sysConfig.boardBorder = _sysConfig.cutBoardBorder;
|
||
|
||
let eleCanvasMain = document.getElementsByClassName('contentMain')[0];
|
||
const { clientWidth, clientHeight } = eleCanvasMain;
|
||
canvasWidth.value = clientWidth - 10;
|
||
canvasHeight.value = clientHeight - 30;
|
||
|
||
await nextTick();
|
||
boardEditor.value = new BoardEditor(
|
||
canvas.value.canvasRef,
|
||
_sysConfig,
|
||
canvasController.value
|
||
);
|
||
|
||
boardEditor.value.boardWidth = sysConfig.boardWidth;
|
||
boardEditor.value.boardLength = sysConfig.boardLength;
|
||
boardEditor.value.drawBase();
|
||
boardEditor.value.setSysConfig(_sysConfig);
|
||
}
|
||
|
||
|
||
async function initHandleServe1() {
|
||
|
||
let newTestData = dataBase.value;
|
||
//#region 刀库
|
||
let toolsHelperClass = new ToolsHelper();
|
||
let contextKnife: ProcessorContext<Knife[], any, any> = {
|
||
input: newTestData.sysConfig.knifeList,
|
||
output: {},
|
||
params: newTestData.sysConfig
|
||
}
|
||
const toolsHelper = toolsHelperClass.exec(contextKnife)
|
||
//#endregion
|
||
|
||
//#region 优化排版
|
||
let input = {
|
||
materialList: newTestData.materialList,
|
||
blockList: newTestData.blockList,
|
||
blockDetailList: newTestData.blockDetailList,
|
||
toolsHelper: toolsHelper,
|
||
}
|
||
let params = newTestData.sysConfig
|
||
|
||
let context: ProcessorContext<any, Function, any> = {
|
||
input: input,
|
||
params: params,
|
||
output: optimizeLayoutProcessorCallBack
|
||
};
|
||
const optimizeLayoutProcessor = new OptimizeLayoutProcessor()
|
||
let res = optimizeLayoutProcessor.exec(context)
|
||
|
||
_handleServe.value = optimizeLayoutProcessor
|
||
//#endregion
|
||
}
|
||
|
||
|
||
/** 优化的处理器回调--这部分 不做到处理器 */
|
||
async function optimizeLayoutProcessorCallBack(context) {
|
||
console.log('optimizeLayoutProcessorCallBack', context);
|
||
const { data, info } = context;
|
||
|
||
if (['noBan', 'stop'].includes(info.type)) {
|
||
await _handleServe.value?.terminateWorker({ goodsId: context.data.pm.goodsId });
|
||
|
||
return;
|
||
}
|
||
|
||
// 优化算法拿到优化数据后 各部门根据情况 将数据加载到各自的数据结构中
|
||
let materialPlaceResult = await getMaterialPlaceResult(data);
|
||
if (materialPlaceResult) {
|
||
const { placeResult, pm } = materialPlaceResult;
|
||
const remain = placeResult.boards.filter(e => e.isRemainBoard == true);
|
||
|
||
for (const i in dataBase.value.materialList) {
|
||
let material = dataBase.value.materialList[i];
|
||
|
||
if (material.goodsId == pm.goodsId) {
|
||
// let hasResPm = _handleServe.value?.handlePlaceResult(placeResult, pm);
|
||
let _hasResPm = await handleTempPlaceResultToPlaceMaterial(placeResult, pm);
|
||
|
||
dataBase.value.materialList[i] = {
|
||
...material,
|
||
...pm,
|
||
..._hasResPm,
|
||
optimizingAvgUsageRateExcludeLastBoard: placeResult.avgUsageRateExcludeLastBoard.toFixed(3),
|
||
optimizingUsageRateLastBoard: placeResult.usageRateLastBoard.toFixed(3),
|
||
optimizingBoardCount: placeResult.boardCount,
|
||
optimizingRemainBoardCount: remain.length,
|
||
selectedBlockCount: pm.blockList.length,
|
||
};
|
||
}
|
||
}
|
||
|
||
setTableData(dataBase.value.materialList);
|
||
}
|
||
}
|
||
|
||
/** 数据处理 将优化数据转 为 MaterialPlaceResult */
|
||
function getMaterialPlaceResult(data) {
|
||
let {
|
||
bList, best, yl, pm, width, length
|
||
} = data
|
||
const config = dataBase.value.sysConfig
|
||
|
||
let blocks = bList
|
||
let retData = new MaterialPlaceResult()
|
||
let boardCount = 0
|
||
let remainCount = 0
|
||
let border = config.cutBoardBorder
|
||
let borderOff = (pm.diameter + pm.cutKnifeGap) / 2
|
||
|
||
|
||
// 所有大板上的小板面积
|
||
let size_all = 0
|
||
|
||
for (let i = 0; i < best.length; i++) {
|
||
let bd = best[i]
|
||
let isRemainBoard = false
|
||
boardCount = retData.boards.length + 1
|
||
if (i < yl.length) // 余料板
|
||
{
|
||
width = yl[i].w + border * 2 - borderOff * 2
|
||
length = yl[i].l + border * 2 - borderOff * 2
|
||
isRemainBoard = true
|
||
remainCount++
|
||
}
|
||
|
||
let boardResult = new BoardPlaceResult()
|
||
boardResult.boardId = boardCount
|
||
boardResult.width = width
|
||
boardResult.length = length
|
||
boardResult.isRemainBoard = isRemainBoard
|
||
|
||
let pid = 0
|
||
for (let b of bd) {
|
||
pid++
|
||
let block = blocks[b.bangid]
|
||
let placeStyle = PlaceStyle.FRONT
|
||
if (!block) {
|
||
return
|
||
}
|
||
let faceF = block.isTurnFaceToPlace || false
|
||
let isTurnFaceToPlace = config.placeOriginByBoardLocation && (
|
||
config.boardLocation == BoardPosition.RIGHT_BOTTOM || config.boardLocation == BoardPosition.LEFT_TOP)
|
||
if (isTurnFaceToPlace)
|
||
faceF = !faceF
|
||
if (faceF) // 翻面开料
|
||
{
|
||
if (block.texture == 0) {
|
||
placeStyle = PlaceStyle.BACK
|
||
}
|
||
else if (block.texture == 2) {
|
||
placeStyle = PlaceStyle.BACK_TURN_LEFT
|
||
}
|
||
else {
|
||
placeStyle = (b.pbg == block.placeFullLength ? PlaceStyle.BACK : PlaceStyle.BACK_TURN_LEFT)
|
||
}
|
||
}
|
||
else {
|
||
if (block.texture == 0) {
|
||
placeStyle = PlaceStyle.FRONT
|
||
}
|
||
else if (block.texture == 2) {
|
||
placeStyle = PlaceStyle.FRONT_TURN_RIGHT
|
||
}
|
||
else {
|
||
placeStyle = (b.pbg == block.placeFullLength ? PlaceStyle.FRONT : PlaceStyle.FRONT_TURN_RIGHT)
|
||
}
|
||
}
|
||
|
||
let br: any = null
|
||
br = new BlockPlaceResult(block.blockNo, boardCount, pid, b.x, b.y, b.pbk, b.pbg, placeStyle, block.area)
|
||
boardResult.blocks.push(br)
|
||
boardResult.area += block.area
|
||
}
|
||
retData.boards.push(boardResult)
|
||
size_all += boardResult.area
|
||
|
||
let val = (size_all - boardResult.area) / (retData.boards.length - 1)
|
||
retData.avgUsageRateAll = size_all / retData.boards.length
|
||
retData.avgUsageRateExcludeLastBoard = Number.isNaN(val) ? boardResult.area : val
|
||
retData.usageRateLastBoard = boardResult.area
|
||
retData.boardCount = retData.boards.length
|
||
}
|
||
retData.boardCount = retData.boards.length // 大板数
|
||
let remainBoardCount = retData.boards.filter(t => t.remainNo != '').length // 异形大板数
|
||
let remianCount = 0
|
||
|
||
if (Array.isArray(pm.remainBoardList)) {
|
||
pm.remainBoardList.forEach(e => {
|
||
if (e?.placeBoardJSON) {
|
||
let str = e?.placeBoardJSON
|
||
e.placeBoardList = JSON.parse(str)
|
||
remianCount += e.placeBoardList.length
|
||
}
|
||
})
|
||
}
|
||
|
||
retData.remainBoardCount = pm?.remainBoardList ? remianCount : yl.length + remainBoardCount
|
||
|
||
|
||
|
||
|
||
return { placeResult: retData, pm }
|
||
}
|
||
|
||
async function handleTempPlaceResultToPlaceMaterial(_placeResult: MaterialPlaceResult, _pm: PlaceMaterial) {
|
||
console.log('确认优化生效 affirmPlace')
|
||
let pm: PlaceMaterial = _pm
|
||
pm.tempBestPlaceResult = _placeResult
|
||
const config = dataBase.value.sysConfig
|
||
// 没发现优化结果
|
||
if (!pm.tempBestPlaceResult)
|
||
return
|
||
|
||
let placeResult = pm.tempBestPlaceResult
|
||
|
||
let orgBoardList = pm.boardList
|
||
|
||
let dic: any = [] // 存放当前 优化的小板
|
||
|
||
pm.boardList = []
|
||
let boardId1 = 1
|
||
// 第一次 false
|
||
if (pm.tempPlaceResultOnyUnlockedBoard) {
|
||
for (let pb of orgBoardList) {
|
||
if (pb.isLocked == false && pb.cutedType == 0) // 未锁定
|
||
{
|
||
pb.blockList.forEach(i => dic[i.blockNo] = i)
|
||
}
|
||
else // 锁定
|
||
{
|
||
if (pb.isAdnormal()) {
|
||
let sb = pm.remainBoardList.find(t => t.id == Number(pb.boardNo))
|
||
if (sb)
|
||
sb.isUsed = true
|
||
}
|
||
pb.boardId = boardId1
|
||
pm.boardList.push(pb)
|
||
boardId1++
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
pm.blockList.forEach(i => dic[i.blockNo] = i)
|
||
}
|
||
|
||
// 0904 修复 需求改造后 导致 这里的dic 最终为空
|
||
if (Object.keys(dic).length == 0) {
|
||
pm.blockList.forEach(i => dic[i.blockNo] = i)
|
||
}
|
||
|
||
let locator = config.boardLocation
|
||
// 大板优化结果
|
||
let boardId = 0
|
||
for (let bpr of placeResult.boards) {
|
||
boardId++
|
||
// bpr.isRemainBoard false
|
||
let bW = bpr.isRemainBoard ? bpr.width : pm.width
|
||
let bL = bpr.isRemainBoard ? bpr.length : pm.length
|
||
let pb = new PlaceBoard(boardId, bW, bL, bpr.remainId, bpr.remainNo)
|
||
pb.isCreateRemainSpace = true
|
||
|
||
for (let bInfo of bpr.blocks) {
|
||
let block: PlaceBlock = dic[bInfo.blockId]
|
||
|
||
if (block) {
|
||
block.isPlaced = true
|
||
block.boardId = boardId
|
||
block.placeId = bInfo.placeId
|
||
block.placeX = bInfo.placeX
|
||
block.placeY = bInfo.placeY
|
||
// console.log('重置 开料面 开料信息 after', block.boardId, block.blockNo, block, block.placeStyle, bInfo.placeStyle)
|
||
|
||
/**
|
||
* 雕刻机(钻孔、拉槽、开料)优化排版,开料排版面(开料正面)选择顺序:排版面>>造型>>排钻>>设计正面
|
||
1. 排版面
|
||
小板设计排版面为正面或反面,设置对应面为开料排版面,
|
||
小板设计排版面为随意面,则继续;
|
||
2. 造型
|
||
小板只有单面造型,设置对应面为开料排版面,
|
||
小板双面无造型或双面有造型,则继续;
|
||
3. 排钻
|
||
小板有大孔(偏心轮锁孔),设置对应面为开料排版面,
|
||
小板无大孔(偏心轮锁孔),则设置孔多的面为开料排版面,
|
||
小板无孔,则继续;
|
||
4. 设计正面
|
||
默认设置设计正面为开料排版面。
|
||
*/
|
||
|
||
block.placeStyle = bInfo.placeStyle
|
||
|
||
let posOff = BlockSizePlus.getOffDis(block)// this.getOffDis(block)
|
||
|
||
block.placeOffX = posOff.x
|
||
block.placeOffY = posOff.y
|
||
block.placeX = bInfo.placeX + posOff.x
|
||
block.placeY = bInfo.placeY + posOff.y
|
||
|
||
if (bInfo.placeStyle == PlaceStyle.FRONT || bInfo.placeStyle == PlaceStyle.FRONT_TURN_BACK
|
||
|| bInfo.placeStyle == PlaceStyle.BACK || bInfo.placeStyle == PlaceStyle.BACK_TURN_BACK) {
|
||
block.placeWidth = block.cutWidth
|
||
block.placeLength = block.cutLength
|
||
}
|
||
else {
|
||
block.placeWidth = block.cutLength
|
||
block.placeLength = block.cutWidth
|
||
}
|
||
|
||
block.isAutoPlaced = true
|
||
block.isOverlap = false
|
||
block.cutOrder = 0
|
||
pb.blockList.push(block)
|
||
pb.blockCount++
|
||
pb.blockArea += block.area
|
||
delete dic[bInfo.blockId] // 移除block;
|
||
} else {
|
||
|
||
}
|
||
}
|
||
if (bpr.isScrap) {
|
||
// 设置前余料板的使用状态,将不需要的释放.
|
||
console.log('设置前余料板的使用状态,将不需要的释放.')
|
||
let sb = pm.remainBoardList.find(t => t.id == bpr.remainId)
|
||
if (sb) {
|
||
sb.isUsed = true
|
||
|
||
if (sb.placeStyle % 2 != 0) {
|
||
pb.width = sb.length
|
||
pb.length = sb.width
|
||
}
|
||
let pl = sb.placePolyline
|
||
pb.points = sb?.placePolyline?.LineData.map((t) => { return { x: t.pt.x, y: t.pt.y, bul: t.bul } }) || []
|
||
// pb.StoreNo = sb.StoreHouse;
|
||
}
|
||
}
|
||
pb.usageRate = Math.round(10000 * pb.blockArea / pb.area) / 100
|
||
pm.boardList.push(pb)
|
||
console.log('大板靠板翻转', pb.boardId, locator)
|
||
|
||
// 大板靠板翻转
|
||
|
||
PlacePositionHelper.turnPlacePosition(pb, locator, config)
|
||
for (let block of pb.blockList) {
|
||
// 重置 开料面 开料信息
|
||
// console.log('重置 开料面 开料信息', block.boardId, block.blockNo, block, block.placeStyle)
|
||
if (block.placeStyle == null || block.placeStyle == undefined) {
|
||
console.log('handleTempPlaceResultToPlaceMaterial error !block.placeStyle is null or undefined')
|
||
} else {
|
||
PlacePositionClass.resetPlaceStyle(block, block.placeStyle)
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
// 大板长边两侧 width 范围内 避免出现造型 DisPoseModelInBoardBorderWidth > 0 生效
|
||
|
||
DisPoseModelInBoardBorder(
|
||
pm,
|
||
config.boardBorderModelRange,
|
||
config.boardBorderModelModeToFace,
|
||
config.boardBorderModelByMachine,
|
||
config.modelNearBoardBorder,
|
||
)
|
||
|
||
// for (let pb of pm.boardList) {
|
||
// // 重设大板汇总 重设 大板开料 顺序,下刀点
|
||
// this.resetPlaceBoard(pm, pb)
|
||
// // 检查干涉
|
||
// if (pb.isLocked == false && pb.cutedType == 0)
|
||
// this.checkOverlapInBoard(pm, pb)
|
||
// }
|
||
|
||
let rBoardCount = placeResult.boardCount
|
||
let rUseSize_avg = placeResult.avgUsageRateAll
|
||
let rUseSize_noLast = placeResult.avgUsageRateExcludeLastBoard
|
||
let rUseSize_last = placeResult.usageRateLastBoard
|
||
|
||
pm.avgUsageRateAll = rUseSize_avg
|
||
pm.avgUsageRateExcludeLastBoard = rUseSize_noLast
|
||
pm.usageRateLastBoard = rUseSize_last
|
||
pm.boardCount = pm.boardList.length
|
||
pm.remainBoardCount = placeResult.remainBoardCount
|
||
pm.minBoardId = 1
|
||
pm.maxBoardId = pm.boardCount
|
||
|
||
pm.edgeSealLengthList = getMaterialSealEdge(pm)
|
||
|
||
pm.boardCountFlipFace = ArrayExt.count(pm.boardList, t => t.isTwoFaceProcessing())
|
||
|
||
pm.isOptimized = true
|
||
pm.tempBestPlaceResult = null
|
||
pm.tempPlaceResultError = ''
|
||
|
||
let mesg = ''
|
||
let c = 0
|
||
for (let v in dic) {
|
||
mesg += `${v} `
|
||
c++
|
||
}
|
||
|
||
mesg = `有${c}片小板未能排入大板,有可能是尖角导致优化失败.${mesg}`
|
||
|
||
if (c > 0) {
|
||
console.log(pm)
|
||
// createMessage.error(mesg)
|
||
|
||
throw new Error(mesg)
|
||
}
|
||
|
||
return pm
|
||
}
|
||
|
||
/**
|
||
* 绘制下刀点
|
||
*/
|
||
function drawCutPoint() {
|
||
if (!boardEditor.value || !dataBase.value || !_handleServe.value) return;
|
||
|
||
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
|
||
let pIndex = paginationCurrent.value - 1;
|
||
|
||
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
|
||
const pm = dataBase.value.materialList[mIndex];
|
||
const pb = pm.boardList[pIndex];
|
||
|
||
// 计算开料顺序和下刀点
|
||
// _handleServe.value.autoCalcCutOrder(pm, pb);
|
||
CutPointHelper.autoFindCutPoint(pm, pb)
|
||
// 设置显示标志位,只显示小板和下刀点
|
||
displayFlags.value.showBlocks = true;
|
||
displayFlags.value.showCutPoints = !displayFlags.value.showCutPoints; // 切换下刀点显示状态
|
||
|
||
// 重新绘制
|
||
// reDrawCanvas();
|
||
} else {
|
||
alert('请先进行优化!');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 绘制开料顺序
|
||
*/
|
||
function drawSortingPlace() {
|
||
if (!boardEditor.value || !dataBase.value || !_handleServe.value) return;
|
||
|
||
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
|
||
let pIndex = paginationCurrent.value - 1;
|
||
|
||
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
|
||
const pm = dataBase.value.materialList[mIndex];
|
||
const pb = pm.boardList[pIndex];
|
||
const config = dataBase.value.sysConfig
|
||
// 计算所有板材的 开料顺序
|
||
let newList = CutOrder.autoSetCutOrder(dataBase.value.materialList, config)
|
||
// 计算当前板材的开料顺序
|
||
// CutOrder.autoCalcCutOrder(pm,pb,false,config)
|
||
// 设置显示标志位,只显示小板和开料顺序
|
||
displayFlags.value.showBlocks = true;
|
||
displayFlags.value.showCutOrders = !displayFlags.value.showCutOrders; // 切换开料顺序显示状态
|
||
|
||
// 重新绘制
|
||
// reDrawCanvas();
|
||
} else {
|
||
alert('请先进行优化!');
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 处理画布事件
|
||
*/
|
||
function boardViewEvent(name, e) {
|
||
if (!boardEditor.value) return;
|
||
|
||
if (name === 'CanvasEvent_MouseDown') {
|
||
// 处理鼠标按下事件
|
||
boardEditor.value.CanvasEvent_MouseDown(e);
|
||
} else if (name === 'CanvasEvent_MouseMove') {
|
||
// 使用节流函数处理鼠标移动事件,减少事件触发频率
|
||
throttledMouseMove(e);
|
||
} else if (name === 'CanvasEvent_Mouseup') {
|
||
boardEditor.value.CanvasEvent_Mouseup(e);
|
||
} else if (name === 'CanvasEvent_dblclick') {
|
||
// 双击事件处理
|
||
} else if (name === 'CanvasEvent_Wheel') {
|
||
// 滚轮事件处理
|
||
} else if (name === 'keyDown') {
|
||
boardEditor.value.keyDown(e);
|
||
}
|
||
}
|
||
|
||
const throttledMouseMove = throttle((e) => {
|
||
if (boardEditor.value) {
|
||
boardEditor.value.CanvasEvent_MouseMove(e);
|
||
}
|
||
}, 16);
|
||
|
||
/**
|
||
* 节流函数
|
||
*/
|
||
function throttle(fn, delay) {
|
||
let lastCall = 0;
|
||
return function (...args) {
|
||
const now = Date.now();
|
||
if (now - lastCall >= delay) {
|
||
lastCall = now;
|
||
fn.apply(this, args);
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* 开始排版
|
||
*/
|
||
function startPlace() {
|
||
// initHandleServe();
|
||
initHandleServe1();
|
||
|
||
// 设置显示标志位,显示所有内容
|
||
displayFlags.value.showBlocks = true;
|
||
displayFlags.value.showCutPoints = true;
|
||
displayFlags.value.showCutOrders = true;
|
||
displayFlags.value.showCutArrow = true;
|
||
displayFlags.value.showCutNo = true;
|
||
displayFlags.value.showHoles = true;
|
||
displayFlags.value.showModels = true;
|
||
}
|
||
|
||
|
||
/**
|
||
* 清空画布
|
||
*/
|
||
function clearCanvas() {
|
||
// 重置显示标志位
|
||
displayFlags.value.showBlocks = false;
|
||
displayFlags.value.showCutPoints = false;
|
||
displayFlags.value.showCutOrders = false;
|
||
displayFlags.value.showCutArrow = false;
|
||
displayFlags.value.showCutNo = false;
|
||
displayFlags.value.showHoles = false;
|
||
displayFlags.value.showModels = false;
|
||
// 清空画布
|
||
boardEditor.value?.clearCanvas();
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取解析器参数
|
||
*/
|
||
function getParserParams() {
|
||
handleTemplateData();
|
||
}
|
||
|
||
|
||
/**
|
||
* 处理模板数据
|
||
*/
|
||
async function handleTemplateData() {
|
||
// 获取模板和范例
|
||
let templateData = parserMain.value._device.getTemplateData();
|
||
console.log(templateData, dataBase.value);
|
||
|
||
if (!currentMaterial.value || !currentBoard.value) {
|
||
alert('请先进行优化!');
|
||
return;
|
||
}
|
||
|
||
// 准备代码参数列表
|
||
let data: CodeParamsList = {
|
||
processList: [],
|
||
};
|
||
|
||
// 获取速度参数
|
||
let freeSpeed = _handleServe.value?.freeSpeed || 10000;
|
||
let workSpeed = _handleServe.value?.workSpeed || 8000;
|
||
let modelSpeed = _handleServe.value?.modelSpeed || 8000;
|
||
let holeSpeed = _handleServe.value?.holeSpeed || 8000;
|
||
|
||
/** 根据哪个加工面加工 */
|
||
let doBackFace = true
|
||
for (const template of templateData) {
|
||
// 必须要有指令和代码
|
||
if (!template.value || !template.orderStr) continue;
|
||
|
||
if (template.isLoop) {
|
||
// 处理循环节点(加工刀路数据)
|
||
let material = currentMaterial.value;
|
||
let board = currentBoard.value;
|
||
// 根据开料顺序做个排序
|
||
board.blockList = board.blockList.sort((a, b) => a.cutOrder - b.cutOrder)
|
||
|
||
//#region 排钻
|
||
|
||
/**
|
||
* 先对该大板内所有小板上的孔进行分析
|
||
*/
|
||
|
||
let allHoles: BlockHole[] = await BlockHelper.GetHoles_BoardAllBlocksByDoFace(board,doBackFace)
|
||
// 对孔列表 根据 孔直径 排序
|
||
allHoles = allHoles.sort((a, b) => a.radius - b.radius)
|
||
|
||
for (const key in allHoles) {
|
||
let hole = allHoles[key]
|
||
let block: PlaceBlock = board.blockList.find(e => e.blockNo == hole.blockNo)
|
||
|
||
// 加工项 孔的
|
||
let temp: CodeParamsObj = {
|
||
processItemInfo: {
|
||
code: template.value,
|
||
order: template.orderStr,
|
||
block: {
|
||
blockNo: block.blockNo,
|
||
cutLength: block.cutLength,
|
||
cutWidth: block.cutWidth
|
||
},
|
||
knife: {
|
||
diameter: hole.radius * 2
|
||
},
|
||
}
|
||
};
|
||
let list: CodeParams[] = [];
|
||
let depth = hole.depth >= block.thickness ? block.thickness : hole.depth
|
||
// 刀移动到孔的安全点
|
||
let moveToHolePoint = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
|
||
moveToHolePoint.dir = 0
|
||
moveToHolePoint.z = 30
|
||
moveToHolePoint.f = freeSpeed
|
||
list.push(moveToHolePoint)
|
||
// 刀下到版面
|
||
let moveToblockToDoHole = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
|
||
moveToblockToDoHole.dir = 0
|
||
moveToblockToDoHole.z = -block.thickness
|
||
moveToblockToDoHole.f = freeSpeed
|
||
list.push(moveToblockToDoHole)
|
||
// 下刀
|
||
let knifeDown_DoHole = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
|
||
knifeDown_DoHole.z = -depth
|
||
knifeDown_DoHole.dir = 1
|
||
knifeDown_DoHole.f = holeSpeed
|
||
list.push(knifeDown_DoHole)
|
||
// 抬刀
|
||
let knifeEnd_DoHoleEnd = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
|
||
knifeEnd_DoHoleEnd.dir = 0
|
||
knifeEnd_DoHoleEnd.z = 30
|
||
knifeEnd_DoHoleEnd.f = freeSpeed
|
||
list.push(knifeEnd_DoHoleEnd)
|
||
|
||
temp.list = list
|
||
|
||
data.processList?.push(temp);
|
||
}
|
||
|
||
//#endregion
|
||
|
||
//#region 造型
|
||
|
||
// 所有造型
|
||
let allModels: BlockModel[] = await BlockHelper.GetModels_BoardAllBlocksByDoFace(board,doBackFace)
|
||
allModels = allModels.sort((a, b) => a.knifeRadius - b.knifeRadius)
|
||
|
||
for (const key in allModels) {
|
||
let model = allModels[key]
|
||
let block: PlaceBlock = board.blockList.find(e => e.blockNo == model.blockNo)
|
||
let { placeX, placeY } = block;
|
||
|
||
let temp: CodeParamsObj = {
|
||
processItemInfo: {
|
||
code: template.value,
|
||
order: template.orderStr,
|
||
block: {
|
||
blockNo: block.blockNo,
|
||
cutLength: block.cutLength,
|
||
cutWidth: block.cutWidth
|
||
},
|
||
knife: {
|
||
diameter: model.realKnifeRadius * 2
|
||
},
|
||
}
|
||
};
|
||
let list: CodeParams[] = [];
|
||
let realPointList:any[] = []
|
||
// model.realPointList.forEach((p,i)=>{
|
||
// if(p.curve !=0 || p.radius != 0){
|
||
|
||
// }
|
||
// })
|
||
for (let index = 0; index < model.realPointList.length; index++) {
|
||
const p = model.realPointList[index];
|
||
let last_p: BlockModelPoint;
|
||
if (index == 0) {
|
||
last_p = model.realPointList[model.realPointList.length - 1]
|
||
} else {
|
||
last_p = model.realPointList[index - 1]
|
||
}
|
||
// p.curve
|
||
// p.radius
|
||
let new_p = { ...p, radius: last_p.radius, curve: last_p.curve }
|
||
realPointList.push(new_p);
|
||
}
|
||
|
||
|
||
let depth = model.depth >= block.thickness ? block.thickness : model.depth
|
||
|
||
// 移动到起点
|
||
let codeLineStart = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
|
||
codeLineStart.dir = 0;
|
||
codeLineStart.z = 30;
|
||
codeLineStart.f = freeSpeed;
|
||
list.push(codeLineStart);
|
||
// 下刀至版面
|
||
let knifeToBlock_DoModel = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
|
||
knifeToBlock_DoModel.dir = 0;
|
||
knifeToBlock_DoModel.z = block.thickness;
|
||
knifeToBlock_DoModel.f = freeSpeed
|
||
list.push(knifeToBlock_DoModel)
|
||
// 扎入 下刀至起点
|
||
let knifeInnerBlock_DoBlock = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
|
||
knifeInnerBlock_DoBlock.dir = 1;
|
||
knifeInnerBlock_DoBlock.z = -depth
|
||
knifeInnerBlock_DoBlock.f = modelSpeed
|
||
list.push(knifeInnerBlock_DoBlock)
|
||
// 开始造型走刀
|
||
for (const modelPoint of realPointList) {
|
||
let codeLineMove = pointToCodeParams(modelPoint.pointX, modelPoint.pointY, placeX, placeY, modelPoint.curve)
|
||
codeLineMove.z = -depth
|
||
codeLineMove.f = modelSpeed
|
||
if (modelPoint.radius != 0) {
|
||
codeLineMove.r = modelPoint.radius
|
||
}
|
||
list.push(codeLineMove)
|
||
}
|
||
// 走刀结束 抬刀
|
||
let endPoint = realPointList[realPointList.length - 1]
|
||
let codeLineEnd = pointToCodeParams(endPoint.pointX, endPoint.pointY, placeX, placeY)
|
||
codeLineEnd.dir = 0
|
||
codeLineEnd.f = freeSpeed
|
||
codeLineEnd.z = 30
|
||
list.push(codeLineEnd)
|
||
temp.list = list
|
||
data.processList?.push(temp);
|
||
}
|
||
//#endregion
|
||
|
||
//#region 开料
|
||
|
||
// 轮廓的集合 开料用
|
||
let borderFinalList = board.blockList.map(e => e.blockDetail.borderContour.borderFinal);
|
||
for (const i in borderFinalList) {
|
||
let block = board.blockList[i];
|
||
let border = borderFinalList[i];
|
||
|
||
// 添加标记
|
||
let temp1: CodeParamsObj = {
|
||
processItemInfo: {
|
||
code: 'MARK',
|
||
order: 'Mark',
|
||
codeParams: block.blockNo + ' cut block'
|
||
}
|
||
};
|
||
data.processList?.push(temp1);
|
||
|
||
// 加工项 开料的
|
||
let temp: CodeParamsObj = {
|
||
processItemInfo: {
|
||
code: template.value,
|
||
order: template.orderStr,
|
||
block: {
|
||
cutLength: block.cutLength,
|
||
cutWidth: block.cutWidth
|
||
},
|
||
knife: {
|
||
diameter: material.diameter
|
||
}
|
||
}
|
||
};
|
||
|
||
// 加工刀路信息 代码生成参数列表
|
||
let list: CodeParams[] = [];
|
||
let { placeX, placeY } = block;
|
||
|
||
// 移动到起点
|
||
let codeLineStart = BoardToCodeParams(border[0], placeX, placeY);
|
||
codeLineStart.dir = 0;
|
||
codeLineStart.z = 30;
|
||
codeLineStart.f = freeSpeed;
|
||
list.push(codeLineStart);
|
||
|
||
// 下刀到板面
|
||
let codeLine1 = BoardToCodeParams(border[0], placeX, placeY);
|
||
codeLine1.dir = 0;
|
||
codeLine1.z = block.thickness;
|
||
codeLine1.f = freeSpeed;
|
||
list.push(codeLine1);
|
||
|
||
// 扎入
|
||
let codeLine2 = BoardToCodeParams(border[0], placeX, placeY);
|
||
codeLine2.dir = 1;
|
||
codeLine2.z = 0;
|
||
codeLine2.f = workSpeed;
|
||
|
||
// 走刀
|
||
for (const p of border) {
|
||
// if (block.blockNo == '25044454400') {
|
||
// debugger
|
||
// }
|
||
let codeLine = BoardToCodeParams(p, placeX, placeY);
|
||
codeLine.z = -block.thickness;
|
||
codeLine.f = workSpeed;
|
||
list.push(codeLine);
|
||
}
|
||
|
||
// 回到起点
|
||
let codeLine3 = BoardToCodeParams(border[0], placeX, placeY);
|
||
codeLine3.z = -block.thickness;
|
||
codeLine3.f = freeSpeed;
|
||
list.push(codeLine3);
|
||
|
||
// 抬刀
|
||
let codeLineEnd = BoardToCodeParams(border[0], placeX, placeY);
|
||
codeLineEnd.dir = 0;
|
||
codeLineEnd.z = 30;
|
||
codeLineEnd.f = freeSpeed;
|
||
list.push(codeLineEnd);
|
||
|
||
temp.list = list;
|
||
data.processList?.push(temp);
|
||
}
|
||
//#endregion
|
||
} else {
|
||
// 处理非循环节点(文件头尾)
|
||
let temp: CodeParamsObj = {
|
||
processItemInfo: {
|
||
code: template.value,
|
||
order: template.orderStr
|
||
}
|
||
};
|
||
|
||
if (template.params) {
|
||
temp.processItemInfo.codeParams = template.params;
|
||
}
|
||
|
||
data.processList?.push(temp);
|
||
}
|
||
}
|
||
|
||
console.log('处理完成', data);
|
||
|
||
// 生成代码
|
||
let str = await parserMain.value.getCode(data);
|
||
testData1.value = str;
|
||
console.log('最终结果', str);
|
||
|
||
}
|
||
|
||
/**
|
||
* 将板轮廓转换为代码参数
|
||
* border 轮廓线
|
||
* placeX 板件优化X坐标
|
||
* placeY 板件优化Y坐标
|
||
*/
|
||
function BoardToCodeParams(border: Curve2d | Arc2d, placeX = 0, placeY = 0): CodeParams {
|
||
let codeLine: CodeParams = {};
|
||
codeLine.x = border.EndPoint.m_X + placeX;
|
||
codeLine.y = border.EndPoint.m_Y + placeY;
|
||
codeLine.dir = 1;
|
||
|
||
if (border instanceof Arc2d || (Reflect.has(border, 'm_Radius') && border['m_Radius'] != 0)) {
|
||
codeLine.r = border.m_Radius;
|
||
if (border.Bul > 0) {
|
||
codeLine.dir = 3;
|
||
} else if (border.Bul < 0) {
|
||
codeLine.dir = 2;
|
||
}
|
||
}
|
||
|
||
return codeLine;
|
||
}
|
||
/**
|
||
* x , y 点坐标
|
||
* hole 孔
|
||
* placeX 板件优化X坐标
|
||
* placeY 板件优化Y坐标
|
||
*/
|
||
|
||
function pointToCodeParams(x, y, placeX = 0, placeY = 0, bul?) {
|
||
let codeLine: CodeParams = {}
|
||
codeLine.x = x + placeX
|
||
codeLine.y = y + placeY
|
||
|
||
if (bul != undefined) {
|
||
if (bul > 0) {
|
||
codeLine.dir = 3
|
||
} else if (bul < 0) {
|
||
codeLine.dir = 2
|
||
}
|
||
}
|
||
return codeLine
|
||
}
|
||
/**
|
||
* 重新绘制画布
|
||
*/
|
||
function reDrawCanvas() {
|
||
if (!boardEditor.value || !dataBase.value) return;
|
||
|
||
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
|
||
let pIndex = paginationCurrent.value - 1;
|
||
|
||
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
|
||
const pm = dataBase.value.materialList[mIndex];
|
||
const pb = pm.boardList[pIndex];
|
||
|
||
// 确保每个板件都有开料顺序和下刀点
|
||
if (_handleServe.value && pb.blockList.some(block => !block.cutOrder)) {
|
||
_handleServe.value.autoCalcCutOrder(pm, pb);
|
||
}
|
||
|
||
boardEditor.value.setMaterial(pm);
|
||
boardEditor.value.setBoard(pb);
|
||
|
||
// 清空画布并绘制基础内容
|
||
boardEditor.value.clearCanvas();
|
||
boardEditor.value.drawBase();
|
||
boardEditor.value.drawBoard(pb);
|
||
|
||
boardEditor.value.setDisplayFlags({
|
||
isLockd: displayFlags.value.isLockd,
|
||
showBlocks: displayFlags.value.showBlocks,
|
||
showCutPoints: displayFlags.value.showCutPoints,
|
||
showCutOrders: displayFlags.value.showCutOrders,
|
||
showCutArrow: displayFlags.value.showCutArrow,
|
||
showCutNo: displayFlags.value.showCutNo,
|
||
showHoles: displayFlags.value.showHoles,
|
||
showModels: displayFlags.value.showModels,
|
||
showManualPlace: displayFlags.value.showManualPlace
|
||
});
|
||
|
||
boardEditor.value.drawAllElements();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<div class="processDemo1">
|
||
<div class="tools">
|
||
<span class="toolItemLabel">生产单号:</span>
|
||
<Input class="toolItem" v-model:value="orderNo" style="width: 170px;" @change="orderNoChange" />
|
||
|
||
<span class="toolItemLabel">机台选择:</span>
|
||
<Select v-model:value="selectedMachineID" placeholder="请选择机台" :get-popup-container="getPopupContainer"
|
||
style="width: 170px;" @change="machineChange">
|
||
<SelectOption v-for="item in machineList" :key="item.id" :value="item.id">
|
||
{{ item.name }}
|
||
</SelectOption>
|
||
</Select>
|
||
|
||
<Button v-if="!isOptimizeing" @click="startPlace">开始优化</Button>
|
||
|
||
<Button @click="drawSortingPlace">开料顺序</Button>
|
||
<Button @click="drawCutPoint">下刀点</Button>
|
||
<Button @click="getParserParams"> 解析器</Button>
|
||
<BasicTable @register="registerTable" />
|
||
</div>
|
||
|
||
<div class="content">
|
||
<div class="contentLeft">
|
||
<div class="contentTools">
|
||
|
||
<Select v-model:value="selectVal" class="plateSelect" :style="{ width: '200px', marginLeft: '10px' }"
|
||
:options="plateSelectOptions" :field-names="{ label: 'goodsName', value: 'goodsId' }"
|
||
@change="reDrawCanvas" />
|
||
|
||
|
||
<Pagination v-model:current="paginationCurrent" @change="reDrawCanvas" :page-size="1" class="platePagination"
|
||
:total="paginationCurrentAll" />
|
||
</div>
|
||
|
||
<div class="contentBtns">
|
||
<Button class="contentBtn" @click="clearCanvas">清空</Button>
|
||
|
||
|
||
<Textarea class="testData" v-model:value="testData1"></Textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 画布区域 -->
|
||
<div class="contentMain" ref="canvasMain">
|
||
<BoardView ref="canvas" class="BoardView" :width="canvasWidth" :height="canvasHeight" tabindex="0"
|
||
@keydown="boardViewEvent('keyDown', $event)" @dblclick="boardViewEvent('CanvasEvent_dblclick', $event)"
|
||
@mousedown="boardViewEvent('CanvasEvent_MouseDown', $event)"
|
||
@mouseup="boardViewEvent('CanvasEvent_Mouseup', $event)"
|
||
@mousemove="boardViewEvent('CanvasEvent_MouseMove', $event)"
|
||
@wheel="boardViewEvent('CanvasEvent_Wheel', $event)"
|
||
@contextmenu="boardViewEvent('CanvasEvent_RightClick', $event)" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style>
|
||
.processDemo1 {
|
||
height: 100%;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: 10px;
|
||
}
|
||
|
||
.tools {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.toolItemLabel {
|
||
margin: auto 0;
|
||
}
|
||
|
||
.content {
|
||
display: flex;
|
||
flex-direction: row;
|
||
}
|
||
|
||
.contentLeft {
|
||
display: flex;
|
||
flex-direction: column;
|
||
flex: 1;
|
||
}
|
||
|
||
.contentTools {
|
||
display: flex;
|
||
flex-direction: row;
|
||
}
|
||
|
||
.BoardView {
|
||
border: 1px solid silver;
|
||
}
|
||
|
||
.contentBtns {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.contentBtn {
|
||
margin: 6px 8px;
|
||
}
|
||
|
||
.testData {
|
||
overflow: auto;
|
||
min-height: 450px !important;
|
||
background-color: #FFFFFF !important;
|
||
color: #000000 !important;
|
||
}
|
||
</style>
|