修改报表生成

master
夜笙歌 3 days ago
parent 44ecadd990
commit 81ad493a92

@ -89,7 +89,7 @@
"@unocss/preset-icons": "0.58.6",
"@unocss/preset-uno": "0.58.6",
"@vitejs/plugin-vue": "5.0.4",
"@vue/compiler-sfc": "3.4.23",
"@vue/compiler-sfc": "3.4.34",
"autoprefixer": "10.4.18",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
@ -116,5 +116,13 @@
"vitest": "1.5.0",
"vue-eslint-parser": "9.4.2",
"vue-tsc": "2.0.13"
},
"overrides": {
"vue": "3.4.34",
"@vue/compiler-core": "3.4.34",
"@vue/runtime-dom": "3.4.34",
"@vue/runtime-core": "3.4.34",
"@vue/reactivity": "3.4.34",
"@vue/shared": "3.4.34"
}
}

@ -51,8 +51,7 @@ service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 请求地址处理兼容使用模块化wms分为wms1\2\3多个微服务端口
config.url = config.url.replaceAll('/wms/',getUrl())
console.log(config.url);
config.url = config.url.replaceAll('/wms/', getUrl());
// 对应国际化资源文件后缀
@ -111,6 +110,12 @@ service.interceptors.request.use(
if (config.data instanceof FormData) {
delete config.headers['Content-Type'];
}
if (config.headers?.bodyType === 'raw') {
if (typeof config.data === 'object') {
config.data = JSON.stringify(config.data);
}
config.headers['Content-Type'] = 'text/plain';
}
return config;
},
(error: any) => {

@ -27,3 +27,11 @@ export const editDataSourceApi = (data) => {
url: '/system/designDataSource', method: 'PUT', data
});
};
// 测试sql连接
export const querySql = (data, db) => {
return request({
url: '/system/databaseLink/querySql/' + db, method: 'post', data, headers: { bodyType: 'raw' }
});
};

@ -153,10 +153,13 @@
<el-dialog v-model="addSQLFormVisible" draggable width="800">
<template #header>
<div style="width: 100%">
<span>{{ constructionDataForm.dataSourceId ? '修改' : '构造' }}数据源</span>
<span>{{ addSQLForm.dataSourceId ? '修改' : '构造' }}数据源</span>
</div>
</template>
<el-form :model="addSQLForm" label-width="auto">
<el-form-item label="数据名称" prop="dataSourceName">
<el-input v-model="addSQLForm.dataSourceName" />
</el-form-item>
<el-form-item label="数据库" prop="db">
<el-select @change="selectDb" v-model="addSQLForm.db" placeholder="选择数据库" style="width: 240px">
<el-option
@ -176,36 +179,71 @@
placeholder=""
/>
</el-form-item>
<el-form-item label="关键字">
<el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in keyword"
@click="addSQLInput(i)">{{ i }}
</el-tag>
</el-form-item>
<el-form-item label="表">
<el-select @change="selectTable" v-model="addSQLForm.table" placeholder="选择表" style="width: 240px">
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.tableName"
:value="item.tableName"
/>
</el-select>
</el-form-item>
<el-form-item label="字段">
<el-tag type="primary" style="margin-right: 8px;margin-bottom: 8px;" @click="addSQLInput(addSQLForm.table)">
{{ addSQLForm.table }}
</el-tag>
<el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in fieldList"
@click="addSQLInput(i.columnName)">{{ i.columnName
}}
</el-tag>
<!-- <el-form-item label="关键字">-->
<!-- <el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in keyword"-->
<!-- @click="addSQLInput(i)">{{ i }}-->
<!-- </el-tag>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="表">-->
<!-- <el-select @change="selectTable" v-model="addSQLForm.table" placeholder="选择表" style="width: 240px">-->
<!-- <el-option-->
<!-- v-for="item in tableList"-->
<!-- :key="item.value"-->
<!-- :label="item.tableName"-->
<!-- :value="item.tableName"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="字段">-->
<!-- <el-tag type="primary" style="margin-right: 8px;margin-bottom: 8px;" @click="addSQLInput(addSQLForm.table)">-->
<!-- {{ addSQLForm.table }}-->
<!-- </el-tag>-->
<!-- <el-tag type="success" style="margin-right: 8px;margin-bottom: 8px;" v-for="i in fieldList"-->
<!-- @click="addSQLInput(i.columnName)">{{ i.columnName-->
<!-- }}-->
<!-- </el-tag>-->
<!-- </el-form-item>-->
<el-form-item label="输出数据">
<el-table :data="addSQLForm.designDataFieldList" style="width: 100%">
<el-table-column label="字段名称" min-width="120">
<template #default="scope">
<el-input v-model="scope.row.fieldOne" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="字段层级" min-width="120">
<template #default="scope">
<el-input v-model="scope.row.fieldTwo" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120">
<template #default="scope">
<el-input v-model="scope.row.remark" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="操作" min-width="120">
<template #default="scope">
<el-button link size="small" type="primary"
@click="addSQLForm.designDataFieldList.splice(scope.$index, 1)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button style="width: 100%" @click="addSQLForm.designDataFieldList.push({})">
添加字段
</el-button>
<el-button style="width: 100%;margin: 12px 0 0 0"
@click="sqlFindTier">
查找
</el-button>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="addSQLFormVisible = false">关闭</el-button>
<el-button type="primary" @click="createSQL ">
{{ constructionDataForm.dataSourceId ? '确定' : '创建' }}
{{ addSQLForm.dataSourceId ? '确定' : '创建' }}
</el-button>
</div>
</template>
@ -216,7 +254,7 @@
import axios from 'axios';
import request from '@/utils/request';
import { options } from './tool.js';
import { addDataSourceApi, delDataSourceApi, editDataSourceApi, getDataSourceList } from './api/dataSource';
import { addDataSourceApi, delDataSourceApi, editDataSourceApi, getDataSourceList, querySql } from './api/dataSource';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getDatabaseLink, getFieldList, listDatabaseLink } from '@/views/boardGenerate/api/db';
@ -278,7 +316,9 @@ const constructionData = () => {
};
const addSQL = () => {
addSQLFormVisible.value = true;
addSQLForm.value = {};
addSQLForm.value = {
designDataFieldList: []
};
getDbList();
};
const getDbList = () => {
@ -300,9 +340,33 @@ const addSQLInput = (data) => {
addSQLForm.value.SQL = (addSQLForm.value.SQL || '') + `${data} `;
};
const testSql = () => {
querySql(addSQLForm.value.SQL, addSQLForm.value.db).then((res) => {
console.log(res);
});
};
const createSQL = () => {
let params = JSON.parse(JSON.stringify(addSQLForm.value));
params.activeFlag = '1';
let params = {
...addSQLForm.value,
dataSourceName: addSQLForm.value.dataSourceName,
activeFlag: '1',
responseType: '2',
designDataFieldList: addSQLForm.value.designDataFieldList.map(e => {
return {
fieldType: '2',
activeFlag: '1',
dataSourceId: addSQLForm.value.dataSourceId,
fieldOne: e.fieldOne,
fieldTwo: e.fieldTwo
};
}),
requestUrl: 'system/databaseLink/querySql',
requestMethod: 'querySql',
fieldOne: addSQLForm.value.db,
fieldTwo: addSQLForm.value.SQL
};
if (addSQLForm.value.dataSourceId) {
editDataSourceApi(params).then(() => {
addSQLFormVisible.value = false;
@ -339,8 +403,20 @@ const delData = () => {
};
const editDataSource = (e) => {
console.log(e);
constructionDataFormVisible.value = true;
constructionDataForm.value = e;
if (e.responseType === '1' || !e.responseType) {
constructionDataFormVisible.value = true;
constructionDataForm.value = e;
}
if (e.responseType === '2') {
addSQLFormVisible.value = true;
addSQLForm.value = {
...e,
db: parseFloat(e.fieldOne),
SQL: e.fieldTwo
};
getDbList();
}
};
const delDataSource = (e) => {
ElMessageBox.confirm(
@ -374,6 +450,7 @@ const createData = () => {
}
let params = JSON.parse(JSON.stringify(constructionDataForm.value));
params.activeFlag = '1';
params.responseType = '1';
params.designDataFieldList = params.designDataFieldList.map(e => {
return {
fieldType: '2',
@ -420,7 +497,6 @@ const findTier = () => {
data: constructionDataForm.value.requestMethod === 'post' ? params : ''
}).then(res => {
let data = (options.isD ? res : res.data);
console.log(data);
if (data?.data) {
Object.keys(data.data?.[0]).forEach(key => {
constructionDataForm.value.designDataFieldList.push({
@ -429,6 +505,11 @@ const findTier = () => {
fieldTwo: `data,map%${key}`
});
});
constructionDataForm.value.designDataFieldList.push({
fieldOne: 'data',
remark: '',
fieldTwo: `data`
});
} else if (data?.rows) {
console.log(data?.rows);
Object.keys(data.rows?.[0]).forEach(key => {
@ -438,6 +519,11 @@ const findTier = () => {
fieldTwo: `rows,map%${key}`
});
});
constructionDataForm.value.designDataFieldList.push({
fieldOne: 'rows',
remark: '',
fieldTwo: `rows`
});
} else {
let exclude = ['code'];
Object.keys(data).forEach(key => {
@ -454,6 +540,55 @@ const findTier = () => {
}
});
};
const sqlFindTier = () => {
addSQLForm.value.designDataFieldList = [];
querySql(addSQLForm.value.SQL, addSQLForm.value.db).then((res) => {
let data = res;
if (data?.data) {
Object.keys(data.data?.[0]).forEach(key => {
addSQLForm.value.designDataFieldList.push({
fieldOne: key,
remark: comparisonTable[key],
fieldTwo: `data,map%${key}`
});
});
addSQLForm.value.designDataFieldList.push({
fieldOne: 'data',
remark: '',
fieldTwo: `data`
});
} else if (data?.rows) {
console.log(data?.rows);
Object.keys(data.rows?.[0]).forEach(key => {
addSQLForm.value.designDataFieldList.push({
fieldOne: key,
remark: comparisonTable[key],
fieldTwo: `rows,map%${key}`
});
});
addSQLForm.value.designDataFieldList.push({
fieldOne: 'rows',
remark: '',
fieldTwo: `rows`
});
} else {
let exclude = ['code'];
Object.keys(data).forEach(key => {
if (!exclude.includes(key.toLowerCase())) {
if (typeof data[key] === 'string' || typeof data[key] === 'string') {
addSQLForm.value.designDataFieldList.push({
fieldOne: key,
remark: comparisonTable[key],
fieldTwo: `${key}`
});
}
}
});
}
});
};
onMounted(async () => {
await queryList();

@ -422,153 +422,185 @@
</div>
<div class="center" @drop="onDrop" v-loading="loading">
<FlowRuler>
<VueFlow :min-zoom="0.01" ref="flowRef" v-model:nodes="nodes" v-model:edges="edges" fit-view-on-init
default-marker-color="#409EFF"
@connect="logEvent('connect', $event)"
@node-click="logEvent('click', $event)"
@pane-click="logEvent('paneClick', $event)"
@node-drag-start="logEvent('nodeDrag', $event)"
@node-contextMenu="logEvent('contextmenu', $event)"
@dragover="onDragOver"
<VueFlow
:min-zoom="0.01"
ref="flowRef"
:snapToGrid="isSnapToGrid"
:snapGrid="[10, 10]"
v-model:nodes="nodes"
v-model:edges="edges"
fit-view-on-init
default-marker-color="#409EFF"
@connect="logEvent('connect', $event)"
@node-click="logEvent('click', $event)"
@pane-click="logEvent('paneClick', $event)"
@node-drag-start="logEvent('nodeDrag', $event)"
@node-contextMenu="logEvent('contextmenu', $event)"
@dragover="onDragOver"
>
<Background :size="1" :gap="20" pattern-color="#BDBDBD" style="background-color: #000" />
<template #node-area="areaNodeProps">
<AreaNode v-bind="areaNodeProps" :pageData="pageData"></AreaNode>
<AreaNode v-bind="areaNodeProps" :pageData="pageData" @resize="(e) => handleResizeStop(e, areaNodeProps)" />
</template>
<template #node-customBoard="customBoardNodeProps">
<CustomBoardNode :inputData=getInputData(customBoardNodeProps.id) v-bind="customBoardNodeProps"
@resize="resize"></CustomBoardNode>
<CustomBoardNode v-bind="customBoardNodeProps" :inputData="getInputData(customBoardNodeProps.id)"
@resize="(e) => handleResizeStop(e, customBoardNodeProps)" />
</template>
<template #node-customData="customDataNodeProps">
<CustomDataNode :inputData=getInputData(customDataNodeProps.id) v-bind="customDataNodeProps"
@resize="resize"></CustomDataNode>
<CustomDataNode v-bind="customDataNodeProps" :inputData="getInputData(customDataNodeProps.id)"
@resize="(e) => handleResizeStop(e, customDataNodeProps)" />
</template>
<template #node-line="lineNodeProps">
<LineNode :inputData=getInputData(lineNodeProps.id)
v-bind="lineNodeProps"
@resize="resize"></LineNode>
<LineNode v-bind="lineNodeProps" :inputData="getInputData(lineNodeProps.id)"
@resize="(e) => handleResizeStop(e, lineNodeProps)" />
</template>
<template #node-multiLines="multiLinesNodeProps">
<MultiLinesNode :inputData=getInputData(multiLinesNodeProps.id) v-bind="multiLinesNodeProps"
@resize="resize"></MultiLinesNode>
<MultiLinesNode v-bind="multiLinesNodeProps" :inputData="getInputData(multiLinesNodeProps.id)"
@resize="(e) => handleResizeStop(e, multiLinesNodeProps)" />
</template>
<template #node-curve="curveNodeProps">
<CurveNode :inputData=getInputData(curveNodeProps.id) v-bind="curveNodeProps"
@resize="resize"></CurveNode>
<CurveNode v-bind="curveNodeProps" :inputData="getInputData(curveNodeProps.id)"
@resize="(e) => handleResizeStop(e, curveNodeProps)" />
</template>
<template #node-multiCurves="multiCurvesNodeProps">
<MultiCurvesNode :inputData=getInputData(multiCurvesNodeProps.id) v-bind="multiCurvesNodeProps"
@resize="resize"></MultiCurvesNode>
<MultiCurvesNode v-bind="multiCurvesNodeProps" :inputData="getInputData(multiCurvesNodeProps.id)"
@resize="(e) => handleResizeStop(e, multiCurvesNodeProps)" />
</template>
<template #node-lineBar="lineBarNodeProps">
<LineBarNode :inputData=getInputData(lineBarNodeProps.id) v-bind="lineBarNodeProps"
@resize="resize"></LineBarNode>
<LineBarNode v-bind="lineBarNodeProps" :inputData="getInputData(lineBarNodeProps.id)"
@resize="(e) => handleResizeStop(e, lineBarNodeProps)" />
</template>
<template #node-bar="barNodeProps">
<BarNode :inputData=getInputData(barNodeProps.id) v-bind="barNodeProps"
@resize="resize"></BarNode>
<BarNode v-bind="barNodeProps" :inputData="getInputData(barNodeProps.id)"
@resize="(e) => handleResizeStop(e, barNodeProps)" />
</template>
<template #node-backgroundBar="backgroundBarNodeProps">
<BackgroundBarNode :inputData=getInputData(backgroundBarNodeProps.id) v-bind="backgroundBarNodeProps"
@resize="resize"></BackgroundBarNode>
<BackgroundBarNode v-bind="backgroundBarNodeProps" :inputData="getInputData(backgroundBarNodeProps.id)"
@resize="(e) => handleResizeStop(e, backgroundBarNodeProps)" />
</template>
<template #node-multiBars="multiBarsNodeProps">
<MultiBarsNode :inputData=getInputData(multiBarsNodeProps.id) v-bind="multiBarsNodeProps"
@resize="resize"></MultiBarsNode>
<MultiBarsNode v-bind="multiBarsNodeProps" :inputData="getInputData(multiBarsNodeProps.id)"
@resize="(e) => handleResizeStop(e, multiBarsNodeProps)" />
</template>
<template #node-pie="pieNodeProps">
<PieNode :inputData=getInputData(pieNodeProps.id) v-bind="pieNodeProps"
@resize="resize"></PieNode>
<PieNode v-bind="pieNodeProps" :inputData="getInputData(pieNodeProps.id)"
@resize="(e) => handleResizeStop(e, pieNodeProps)" />
</template>
<template #node-annular="annularNodeProps">
<AnnularNode :inputData=getInputData(annularNodeProps.id)
v-bind="annularNodeProps"
@resize="resize"></AnnularNode>
<AnnularNode v-bind="annularNodeProps" :inputData="getInputData(annularNodeProps.id)"
@resize="(e) => handleResizeStop(e, annularNodeProps)" />
</template>
<template #node-radar="radarNodeProps">
<RadarNode :inputData=getInputData(radarNodeProps.id)
v-bind="radarNodeProps"
@resize="resize"></RadarNode>
<RadarNode v-bind="radarNodeProps" :inputData="getInputData(radarNodeProps.id)"
@resize="(e) => handleResizeStop(e, radarNodeProps)" />
</template>
<template #node-dashboard="dashboardNodeProps">
<DashboardNode :inputData=getInputData(dashboardNodeProps.id)
v-bind="dashboardNodeProps"
@resize="resize"></DashboardNode>
<DashboardNode v-bind="dashboardNodeProps" :inputData="getInputData(dashboardNodeProps.id)"
@resize="(e) => handleResizeStop(e, dashboardNodeProps)" />
</template>
<template #node-nightingaleRoseDiagram="nightingaleRoseDiagramNodeProps">
<NightingaleRoseDiagramNode :inputData=getInputData(nightingaleRoseDiagramNodeProps.id)
v-bind="nightingaleRoseDiagramNodeProps"
@resize="resize"></NightingaleRoseDiagramNode>
<NightingaleRoseDiagramNode v-bind="nightingaleRoseDiagramNodeProps"
:inputData="getInputData(nightingaleRoseDiagramNodeProps.id)"
@resize="(e) => handleResizeStop(e, nightingaleRoseDiagramNodeProps)" />
</template>
<template #node-carousel="carouselNodeProps">
<CarouselNode :inputData=getInputData(carouselNodeProps.id) v-bind="carouselNodeProps"
@resize="resize"></CarouselNode>
<CarouselNode v-bind="carouselNodeProps" :inputData="getInputData(carouselNodeProps.id)"
@resize="(e) => handleResizeStop(e, carouselNodeProps)" />
</template>
<template #node-data="dataNodeProps">
<DataNode :inputData=getInputData(dataNodeProps.id) v-bind="dataNodeProps"
@resize="resize"></DataNode>
<DataNode v-bind="dataNodeProps" :inputData="getInputData(dataNodeProps.id)"
@resize="(e) => handleResizeStop(e, dataNodeProps)" />
</template>
<template #node-text="textNodeProps">
<TextNode :inputData=getInputData(textNodeProps.id) v-bind="textNodeProps"
@resize="resize"></TextNode>
<TextNode v-bind="textNodeProps" :inputData="getInputData(textNodeProps.id)"
@resize="(e) => handleResizeStop(e, textNodeProps)" />
</template>
<template #node-img="imgNodeProps">
<ImgNode :inputData=getInputData(imgNodeProps.id) v-bind="imgNodeProps"
@resize="resize"></ImgNode>
<ImgNode v-bind="imgNodeProps" :inputData="getInputData(imgNodeProps.id)"
@resize="(e) => handleResizeStop(e, imgNodeProps)" />
</template>
<template #node-icon="iconNodeProps">
<IconNode :inputData=getInputData(iconNodeProps.id) v-bind="iconNodeProps"
@resize="resize"></IconNode>
<IconNode v-bind="iconNodeProps" :inputData="getInputData(iconNodeProps.id)"
@resize="(e) => handleResizeStop(e, iconNodeProps)" />
</template>
<template #node-video="videoNodeProps">
<VideoNode :inputData=getInputData(videoNodeProps.id) v-bind="videoNodeProps"
@resize="resize"></VideoNode>
<VideoNode v-bind="videoNodeProps" :inputData="getInputData(videoNodeProps.id)"
@resize="(e) => handleResizeStop(e, videoNodeProps)" />
</template>
<template #node-timeline="timelineNodeProps">
<TimelineNode :inputData=getInputData(timelineNodeProps.id) v-bind="timelineNodeProps"
@resize="resize"></TimelineNode>
<TimelineNode v-bind="timelineNodeProps" :inputData="getInputData(timelineNodeProps.id)"
@resize="(e) => handleResizeStop(e, timelineNodeProps)" />
</template>
<template #node-digitalFlop="digitalFlopNodeProps">
<DigitalFlopNode :inputData=getInputData(digitalFlopNodeProps.id) v-bind="digitalFlopNodeProps"
@resize="resize"></DigitalFlopNode>
<DigitalFlopNode v-bind="digitalFlopNodeProps" :inputData="getInputData(digitalFlopNodeProps.id)"
@resize="(e) => handleResizeStop(e, digitalFlopNodeProps)" />
</template>
<template #node-inputNode="inputNodeProps">
<InputNode :inputData=getInputData(inputNodeProps.id) v-bind="inputNodeProps"
@resize="resize"></InputNode>
</template>
<template #node-time="timeNodeProps">
<TimeNode :inputData=getInputData(timeNodeProps.id) v-bind="timeNodeProps"
@resize="resize"></TimeNode>
</template>
<template #node-map="mapNodeProps">
<MapNode :inputData=getInputData(mapNodeProps.id) v-bind="mapNodeProps"
@resize="resize"></MapNode>
</template>
<template #node-staticData="staticDataNodeProps">
<StaticDataNode :inputData=getInputData(staticDataNodeProps.id) v-bind="staticDataNodeProps"
@resize="resize"></StaticDataNode>
</template>
<template #node-table="tableNodeProps">
<TableNode :inputData=getInputData(tableNodeProps.id) v-bind="tableNodeProps"
@resize="resize"></TableNode>
</template>
<template #node-scrollTable="scrollTableNodeProps">
<ScrollTableNode :inputData=getInputData(scrollTableNodeProps.id) v-bind="scrollTableNodeProps"
@resize="resize"></ScrollTableNode>
</template>
<template #node-background="backgroundNodeProps">
<BackgroundNode :inputData=getInputData(backgroundNodeProps.id) v-bind="backgroundNodeProps"
@resize="resize"></BackgroundNode>
</template>
<template #node-pagination="paginationNodeProps">
<PaginationNode :inputData=getInputData(paginationNodeProps.id) v-bind="paginationNodeProps"
@resize="resize"></PaginationNode>
<InputNode v-bind="inputNodeProps" :inputData="getInputData(inputNodeProps.id)"
@resize="(e) => handleResizeStop(e, inputNodeProps)" />
</template>
<template #node-time="timeNodeProps">
<TimeNode v-bind="timeNodeProps" :inputData="getInputData(timeNodeProps.id)"
@resize="(e) => handleResizeStop(e, timeNodeProps)" />
</template>
<template #node-map="mapNodeProps">
<MapNode v-bind="mapNodeProps" :inputData="getInputData(mapNodeProps.id)"
@resize="(e) => handleResizeStop(e, mapNodeProps)" />
</template>
<template #node-staticData="staticDataNodeProps">
<StaticDataNode v-bind="staticDataNodeProps" :inputData="getInputData(staticDataNodeProps.id)"
@resize="(e) => handleResizeStop(e, staticDataNodeProps)" />
</template>
<template #node-table="tableNodeProps">
<TableNode v-bind="tableNodeProps" :inputData="getInputData(tableNodeProps.id)"
@resize="(e) => handleResizeStop(e, tableNodeProps)" />
</template>
<template #node-scrollTable="scrollTableNodeProps">
<ScrollTableNode v-bind="scrollTableNodeProps" :inputData="getInputData(scrollTableNodeProps.id)"
@resize="(e) => handleResizeStop(e, scrollTableNodeProps)" />
</template>
<template #node-background="backgroundNodeProps">
<BackgroundNode v-bind="backgroundNodeProps" :inputData="getInputData(backgroundNodeProps.id)"
@resize="(e) => handleResizeStop(e, backgroundNodeProps)" />
</template>
<template #node-pagination="paginationNodeProps">
<PaginationNode v-bind="paginationNodeProps" :inputData="getInputData(paginationNodeProps.id)"
@resize="(e) => handleResizeStop(e, paginationNodeProps)" />
</template>
</VueFlow>
</FlowRuler>
</div>
<div class="right">
@ -891,10 +923,10 @@
<el-input v-model="nodeAttrForm.field" />
</el-form-item>
<el-form-item label="每页个数字段" v-if="Object.keys(nodeAttrForm).includes('pageSizeField')">
<el-input v-model="nodeAttrForm.field" />
<el-input v-model="nodeAttrForm.pageSizeField" />
</el-form-item>
<el-form-item label="当前页字段" v-if="Object.keys(nodeAttrForm).includes('currentPageField')">
<el-input v-model="nodeAttrForm.field" />
<el-input v-model="nodeAttrForm.currentPageField" />
</el-form-item>
<el-form-item label="时间戳字段名" v-if="Object.keys(nodeAttrForm).includes('timestampField')">
<el-input v-model="nodeAttrForm.timestampField" />
@ -1472,19 +1504,8 @@ import imgImg from './images/imgImg.png';
import textImg from './images/textImg.png';
import FlowRuler from './FlowRuler.vue';
import {
ArrowDown,
View,
DocumentChecked,
Close,
Plus,
Setting,
StarFilled,
Delete,
Unlock,
Lock
} from '@element-plus/icons-vue';
import * as icon from '@element-plus/icons-vue';
import { ArrowDown, Close, Delete, DocumentChecked, Lock, Plus, Setting, Unlock, View } from '@element-plus/icons-vue';
import { MarkerType, useVueFlow, VueFlow } from '@vue-flow/core';
import tool, { options } from '@/views/boardGenerate/tool.js';
import { v4 as uuidv4 } from 'uuid';
@ -1533,6 +1554,17 @@ const headers = ref(globalHeaders());
const { onDragStart, onDrop, onDragOver } = tool();
const router = useRouter();
const isSnapToGrid = ref(true);
const toggleSnapToGrid = (e) => {
if (e.key === 'Alt') {
isSnapToGrid.value = false;
}
};
const keyup = () => {
isSnapToGrid.value = true;
};
window.addEventListener('keydown', toggleSnapToGrid);
window.addEventListener('keyup', keyup);
const {
addEdges,
updateNode,
@ -1540,6 +1572,22 @@ const {
addNodes
} = useVueFlow();
const gridSize = 200;
const handleResizeStop = (event, node) => {
if (event.altKey) return;
const snappedWidth = Math.round(node.width / gridSize) * gridSize;
const snappedHeight = Math.round(node.height / gridSize) * gridSize;
updateNode(node.id, {
style: {
width: `${snappedWidth}px`,
height: `${snappedHeight}px`
}
});
};
onMounted(async () => {
icons.value = Object.keys(icon);
loading.value = true;
@ -1553,7 +1601,10 @@ onMounted(async () => {
name: e.dataSourceName,
url: e.requestUrl,
method: e.requestMethod,
outputData: e.designDataFieldList
outputData: e.designDataFieldList,
type: e.responseType,
db: e.fieldOne,
SQL: e.fieldTwo
};
});
})
@ -1679,10 +1730,8 @@ const logEvent = async (eventname, event) => {
nodeAttrForm.value = event.node.data.options;
nodeDataForm.value = event.node;
customDataForm.value = event.node.data.customData;
console.log(nodeDataForm.value);
break;
case 'nodeDrag':
console.log(event.nodes);
if (event.nodes.length === 1) {
nodeAttrForm.value = event.node.data.options;
nodeDataForm.value = event.node;
@ -1694,7 +1743,6 @@ const logEvent = async (eventname, event) => {
}
break;
case 'contextmenu':
console.log('contextmenu', event);
}
};
const resize = (e, id) => {
@ -1757,23 +1805,39 @@ const save = () => {
}
}
});
return {
activeFlag: '1',
pageConfigId: boardData.value.pageConfigId,
pagePointId: e.id,
pagePointName: e.name,
fieldOne: index,
fieldTwo: e.draggable,
width: e.dimensions.width,
height: e.dimensions.height,
posX: e.position.x,
posY: e.position.y,
pointType: e.type,
dataContent: JSON.stringify(data)
};
if (e.type === 'area') {
return {
activeFlag: '1',
pageConfigId: boardData.value.pageConfigId,
pagePointId: e.id,
pagePointName: e.name,
fieldOne: index,
fieldTwo: e.draggable,
width: e.dimensions.width || '',
height: e.dimensions.height || '',
posX: e.position.x,
posY: e.position.y,
pointType: e.type,
dataContent: JSON.stringify(data)
};
} else {
return {
activeFlag: '1',
pageConfigId: boardData.value.pageConfigId,
pagePointId: e.id,
pagePointName: e.name,
fieldOne: index,
fieldTwo: e.draggable,
width: e.dimensions.width || '',
height: e.dimensions.height || '',
posX: e.position.x,
posY: e.position.y,
pointType: e.type,
dataContent: JSON.stringify(data)
};
}
}),
designPageEdgesList: edges.value.map(e => {
console.log(e);
return {
activeFlag: '1',
pageConfigId: boardData.value.pageConfigId,
@ -1898,15 +1962,16 @@ const pitchOnNode = (e) => {
};
const cellClick = (e) => {
let option = (nodeAttrForm.value.tableCellOptions || []).find(v => v.index === e.$index && v.cellIndex === e.cellIndex) || {};
console.log(e);
cellOption.value = {
...(nodeAttrForm.value.tableOptions?.[e.cellIndex] || {}),
$index: e.$index,
$cellIndex: e.cellIndex
$cellIndex: e.cellIndex,
formula: option.formula,
type: option.type
};
console.log(e);
cellOptionsVisible.value = true;
console.log(cellOption.value);
};
const cellTypeChange = (value) => {
@ -1926,11 +1991,9 @@ const cellTypeChange = (value) => {
} else {
nodeAttrForm.value.tableCellOptions[index].type = value;
}
console.log(nodeAttrForm.value);
};
const cellFormulaChange = (value) => {
console.log(value);
if (!nodeAttrForm.value.tableCellOptions) {
nodeAttrForm.value.tableCellOptions = [];
}
@ -1947,12 +2010,14 @@ const cellFormulaChange = (value) => {
} else {
nodeAttrForm.value.tableCellOptions[index].formula = value;
}
console.log(nodeAttrForm.value);
};
const formulaFun = (row, formula) => {
let data = formula.replace(/\$\{\s*([^}]+?)\s*\}/g, (_, key) => {
if (key === 'tableData') {
return key;
}
if (`${row[key]}`?.trim() !== '' && !isNaN(row[key])) {
return row[key] || 0;
} else {
@ -1961,7 +2026,8 @@ const formulaFun = (row, formula) => {
});
let res = 0;
try {
res = eval(data);
const fun = new Function('tableData', `return ${data}`);
res = fun((getInputData(nodeDataForm.value.id) || {}).tableData);
} catch (err) {
res = 0;
}
@ -2100,6 +2166,16 @@ const setText = (value, row, formula) => {
height: calc(100vh - var(--boardGenerateTopHeight));
overflow: auto;
/deep/ .vue-flow__resize-control {
background-color: #409EFF !important;
border: 1px solid white;
.handle {
background-color: #409EFF !important;
}
}
}
.right {

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" @resizeEnd="(e) => $emit('resize', e)" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,8 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff"
v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
@ -24,6 +25,7 @@ import { Handle, Position } from '@vue-flow/core';
import request from '@/utils/request';
import axios from 'axios';
import { options } from '../../tool.js';
import { querySql } from '@/views/boardGenerate/api/dataSource.js';
const isErr = ref(false);
const props = defineProps({
@ -81,12 +83,24 @@ const parseData = (data, rule) => {
return resData;
};
const formulaFun = (formula) => {
let data = formula.replace(/\$\{\s*([^}]+?)\s*\}/g, (_, key) => {
console.log(props.inputData);
if (`${props.inputData[key]}`?.trim() !== '' && !isNaN(props.inputData[key])) {
return props.inputData[key] || '';
} else {
return `${props.inputData[key]}`;
}
});
return data;
};
const getOutputData = () => {
let params = props.inputData;
(Object.keys(props.inputData) || []).forEach((item) => {
params[item.name] = props.inputData[item.name];
});
if (props.data.customData.type === '1' || !props.data.customData.type) {
(options.isD ? request : axios.request)({
method: props.data.customData.method,
url: props.data.customData.url,
@ -94,7 +108,7 @@ const getOutputData = () => {
data: props.data.customData.method === 'post' ? params : ''
}).then(res => {
isErr.value = false;
let data = (options.isD ? res : res.data);
let data = (options.isD ? res : res.data || res.rows);
let output = {};
props.data.customData.outputData.forEach(item => {
output[item.fieldOne] = parseData(data, item.fieldTwo);
@ -103,6 +117,22 @@ const getOutputData = () => {
}).catch(e => {
isErr.value = true;
});
}
if (props.data.customData.type === '2') {
querySql(formulaFun(props.data.customData.SQL), props.data.customData.db).then((res) => {
console.log(res);
isErr.value = false;
let data = res;
let output = {};
props.data.customData.outputData.forEach(item => {
output[item.fieldOne] = parseData(data, item.fieldTwo);
});
props.data.outputData = output;
}).catch(e => {
isErr.value = true;
});
}
};
onMounted(() => {

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer :color="dataIsJson?'#ff0000':'#fff'" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" :color="dataIsJson?'#ff0000':'#fff'" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -0,0 +1,372 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
<el-table
:data="getData(props.inputData.tableData)"
v-if="scrollShow"
style="--el-table-border-color:#000"
:border="true"
:show-header="false"
:style="{height: '100%'}"
>
<el-table-column v-for="(i,k) in props.data.options.cellNum" :key="k" :align="i.align" prop="date"
:label="i.name"
:width="i.width">
<template #default="scope">
<div>
<span
v-if="(scope.row[`cellType${k+1}`] || i.type) === '文本'">{{ setText(scope.row[i.field], scope.row, (scope.row[`cellFormula${k + 1}`] || i.formula))
}}</span>
<el-tag type="primary" v-else-if="(scope.row[`cellType${k+1}`] || i.type) === ''">
{{ setText(scope.row[i.field], scope.row, (scope.row[`cellFormula${k + 1}`] || i.formula)) }}
</el-tag>
<el-image :preview-src-list="[scope.row[i.field]]"
v-else-if="(scope.row[`cellType${k+1}`] || i.type) === '图片'" style="width: 100%;"
:style="{height:props.data.options.tdHeight}"
:src="setText(scope.row[i.field],scope.row,(scope.row[`cellFormula${k+1}`] || i.formula))"
fit="contain" />
<el-progress v-else-if="(scope.row[`cellType${k+1}`] || i.type) === ''" :text-inside="true"
:stroke-width="26"
:percentage="parseFloat(setText(scope.row[i.field],scope.row, (scope.row[`cellFormula${k+1}`] || i.formula)))" />
<span v-else>{{ setText(scope.row[i.field], scope.row, (scope.row[`cellFormula${k + 1}`] || i.formula))
}}</span>
</div>
</template>
</el-table-column>
</el-table>
</div>
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
</div>
</template>
<script setup>
import { defineEmits, defineProps, ref } from 'vue';
import { NodeResizer } from '@vue-flow/node-resizer';
import { Handle, Position } from '@vue-flow/core';
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
const a = {
'tableData': [
{
'生产日期': '2024/8/2',
'销售订单': 'G-00101',
'产品名称': '圆珠笔',
'规格型号': '0.5mm',
'单位': '个',
'计划产量': 50,
'实际产量': 45,
'不良数量': 10,
'完成率': '90.00%',
'用时': '2小时',
'备注': ''
},
{
'生产日期': '2024/8/3',
'销售订单': 'G-00110',
'产品名称': '订书机',
'规格型号': '小型',
'单位': '个',
'计划产量': 100,
'实际产量': 99,
'不良数量': 11,
'完成率': '99.00%',
'用时': '3小时',
'备注': ''
},
{
'生产日期': '2024/8/4',
'销售订单': 'G-00111',
'产品名称': '笔记本',
'规格型号': 'A5',
'单位': '个',
'计划产量': 150,
'实际产量': 130,
'不良数量': 15,
'完成率': '86.67%',
'用时': '4小时',
'备注': ''
},
{
'生产日期': '2024/8/5',
'销售订单': 'G-00568',
'产品名称': '笔筒',
'规格型号': '500mm',
'单位': '个',
'计划产量': 200,
'实际产量': 195,
'不良数量': 20,
'完成率': '97.50%',
'用时': '5小时',
'备注': ''
},
{
'生产日期': '2024/8/6',
'销售订单': 'G-00365',
'产品名称': '毛笔',
'规格型号': '小楷笔',
'单位': '个',
'计划产量': 250,
'实际产量': 243,
'不良数量': 22,
'完成率': '97.20%',
'用时': '6小时',
'备注': ''
},
{
'生产日期': '2024/8/7',
'销售订单': 'G-00486',
'产品名称': '铅笔',
'规格型号': '184mm',
'单位': '个',
'计划产量': 300,
'实际产量': 289,
'不良数量': 21,
'完成率': '96.33%',
'用时': '7小时',
'备注': ''
},
{
'生产日期': '2024/8/8',
'销售订单': 'G-00321',
'产品名称': '文件袋',
'规格型号': '240mm',
'单位': '个',
'计划产量': 350,
'实际产量': 345,
'不良数量': 25,
'完成率': '98.57%',
'用时': '8小时',
'备注': ''
},
{
'生产日期': '2024/8/9',
'销售订单': 'G-00462',
'产品名称': '文件盒',
'规格型号': '500mm',
'单位': '个',
'计划产量': 400,
'实际产量': 396,
'不良数量': 26,
'完成率': '99.00%',
'用时': '9小时',
'备注': ''
},
{
'生产日期': '2024/8/10',
'销售订单': 'G-00466',
'产品名称': '水墨笔',
'规格型号': '黑色',
'单位': '个',
'计划产量': 450,
'实际产量': 441,
'不良数量': 27,
'完成率': '98.00%',
'用时': '10小时',
'备注': ''
},
{
'生产日期': '2024/8/11',
'销售订单': 'G-00468',
'产品名称': '橡皮擦',
'规格型号': '小熊',
'单位': '个',
'计划产量': 500,
'实际产量': 498,
'不良数量': 100,
'完成率': '99.60%',
'用时': '11小时',
'备注': ''
},
{
'生产日期': '2024/8/12',
'销售订单': 'G-00500',
'产品名称': '日历',
'规格型号': 'A5',
'单位': '个',
'计划产量': 550,
'实际产量': 530,
'不良数量': 150,
'完成率': '96.36%',
'用时': '12小时',
'备注': ''
},
{
'生产日期': '2024/8/13',
'销售订单': 'G-00510',
'产品名称': '双面胶',
'规格型号': '100m',
'单位': '个',
'计划产量': 600,
'实际产量': 580,
'不良数量': 35,
'完成率': '96.67%',
'用时': '13小时',
'备注': ''
},
{
'生产日期': '2024/8/14',
'销售订单': 'G-00511',
'产品名称': 'A4纸',
'规格型号': '500张',
'单位': '个',
'计划产量': 650,
'实际产量': 610,
'不良数量': 50,
'完成率': '93.85%',
'用时': '14小时',
'备注': ''
},
{
'生产日期': '2024/8/15',
'销售订单': 'G-00515',
'产品名称': '美工刀',
'规格型号': '小',
'单位': '个',
'计划产量': 700,
'实际产量': 670,
'不良数量': 100,
'完成率': '95.71%',
'用时': '15小时',
'备注': ''
},
{
'生产日期': '2024/8/16',
'销售订单': 'G-00518',
'产品名称': '剪刀',
'规格型号': '中',
'单位': '个',
'计划产量': 600,
'实际产量': 500,
'不良数量': 60,
'完成率': '83.33%',
'用时': '16小时',
'备注': ''
},
{
'生产日期': '2024/8/17',
'销售订单': 'G-00520',
'产品名称': '墨水',
'规格型号': '红色',
'单位': '个',
'计划产量': 500,
'实际产量': 420,
'不良数量': 80,
'完成率': '84.00%',
'用时': '17小时',
'备注': ''
},
{
'生产日期': '2024/8/18',
'销售订单': 'G-00525',
'产品名称': '文具盒',
'规格型号': '卡通',
'单位': '个',
'计划产量': 500,
'实际产量': 450,
'不良数量': 100,
'完成率': '90.00%',
'用时': '18小时',
'备注': ''
}
]
};
const scrollShow = ref(true);
const props = defineProps({
isView: {
type: Boolean,
required: false
},
inputData: {
type: Object,
required: false
},
id: {
type: String,
required: true
},
isHideHandle: {
type: Boolean,
required: false
},
selected: {
type: Boolean,
required: false
},
data: {
type: Object,
required: true
},
dimensions: {
type: Object,
required: true
}
});
const formulaFun = (row, formula) => {
let data = formula.replace(/\$\{\s*([^}]+?)\s*\}/g, (_, key) => {
if (key === 'tableData') {
return key;
}
if (`${row[key]}`?.trim() !== '' && !isNaN(row[key])) {
return row[key] || 0;
} else {
return `"${row[key]}"`;
}
});
let res = 0;
try {
const fun = new Function('tableData', `return ${data}`);
res = fun(getData(props.inputData.tableData));
} catch (err) {
res = 0;
}
if (`${res}`.trim() !== '' && !isNaN(res)) {
res = res.toFixed(2);
}
return res;
};
const setText = (value, row, formula) => {
if (!formula) {
return value;
} else {
return formulaFun(row, formula);
}
};
const getData = (e) => {
let val = e;
(props.data.options.tableCellOptions || []).forEach(item => {
e[item.index][`cellType${item.cellIndex + 1}`] = item.type;
e[item.index][`cellFormula${item.cellIndex + 1}`] = item.formula;
});
return e;
};
watch(() => JSON.parse(JSON.stringify([props.inputData?.tableData || '', props.data.options])), (obj1, obj2) => {
if (JSON.stringify(obj1) !== JSON.stringify(obj2)) {
scrollShow.value = false;
nextTick(() => {
scrollShow.value = true;
});
}
}, { deep: true, immediate: true });
const emit = defineEmits(['resize']);
const resize = (e) => {
emit('resize', e, props.id);
};
</script>
<style scoped>
.custom-node {
position: absolute;
}
.scrollTable {
display: inline-block;
vertical-align: top;
}
</style>

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
:style="{color:'#fff',width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,8 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff"
v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
@ -10,7 +11,7 @@
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[100, 200, 300, 400]"
:page-sizes="[1,5,10,20,50,100,200,500,1000]"
:size="size"
:disabled="disabled"
:background="background"
@ -31,31 +32,13 @@ import { NodeResizer } from '@vue-flow/node-resizer';
import { Handle, Position } from '@vue-flow/core';
const currentPage = ref(4);
const currentPage = ref(1);
const pageSize = ref(100);
const total = ref(300);
const pageSize = ref(10);
const total = ref(1);
const size = ref('default');
const background = ref(false);
const disabled = ref(false);
const getOutput = () => {
let output = {
pageSize: pageSize.value,
currentPage: currentPage.value
};
props.data.outputData = output;
};
const handleSizeChange = (val) => {
getOutput();
};
const handleCurrentChange = (val) => {
getOutput();
};
onMounted(() => {
getOutput();
});
const props = defineProps({
isView: {
type: Boolean,
@ -87,13 +70,35 @@ const props = defineProps({
}
});
const getOutput = () => {
let output = {
[props.data.options.pageSizeField || 'pageSize']: pageSize.value,
[props.data.options.currentPageField || 'currentPage']: currentPage.value
};
props.data.outputData = output;
};
const handleSizeChange = (val) => {
getOutput();
};
const handleCurrentChange = (val) => {
getOutput();
};
onMounted(() => {
getOutput();
});
const emit = defineEmits(['resize']);
const resize = (e) => {
emit('resize', e, props.id);
};
watch(() => JSON.parse(JSON.stringify(props.inputData || '{}')), (obj1, obj2) => {
if (JSON.stringify(obj1) !== JSON.stringify(obj2)) {
total.value = props.inputData?.total || 0;
if (Array.isArray(props.inputData?.total)) {
total.value = props.inputData?.total[0] || 0;
} else {
total.value = props.inputData?.total || 0;
}
}
}, { deep: true, immediate: true });
</script>

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
@ -91,7 +91,7 @@ const setText = (value, formula) => {
if (!formula) {
return value;
} else {
}
};
watch(() => JSON.parse(JSON.stringify([props.inputData?.tableData || '', props.data.options])), (obj1, obj2) => {

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
@ -277,13 +277,9 @@ const a = {
]
};
const aa = '${type} - ${aa}';
const scrollShow = ref(true);
const classOptions = ref({
limitMoveNum: 5
});
const props = defineProps({
isView: {
type: Boolean,
@ -316,6 +312,9 @@ const props = defineProps({
});
const formulaFun = (row, formula) => {
let data = formula.replace(/\$\{\s*([^}]+?)\s*\}/g, (_, key) => {
if (key === 'tableData') {
return key;
}
if (`${row[key]}`?.trim() !== '' && !isNaN(row[key])) {
return row[key] || 0;
} else {
@ -324,7 +323,8 @@ const formulaFun = (row, formula) => {
});
let res = 0;
try {
res = eval(data);
const fun = new Function('tableData', `return ${data}`);
res = fun(getData(props.inputData.tableData));
} catch (err) {
res = 0;
}
@ -337,7 +337,6 @@ const setText = (value, row, formula) => {
if (!formula) {
return value;
} else {
console.log(formula);
return formulaFun(row, formula);
}
};
@ -347,7 +346,6 @@ const getData = (e) => {
e[item.index][`cellType${item.cellIndex + 1}`] = item.type;
e[item.index][`cellFormula${item.cellIndex + 1}`] = item.formula;
});
console.log(e);
return e;
};
watch(() => JSON.parse(JSON.stringify([props.inputData?.tableData || '', props.data.options])), (obj1, obj2) => {

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">

@ -1,7 +1,7 @@
<template>
<div
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected"
@resize="resize" />
<div class="custom-node"

@ -328,12 +328,22 @@ const getOption = (e) => {
thBgColor: '#1E90FF',
tdBgColor: ['#0D2B3D', '#103B4C', '#14576B', '#187E99']
};
} else if (e === 'customTable') {
return {
tableOptions: [],
tableCellOptions: [],
cellNum: 2,
dataNum: 2,
tdHeight: '28px',
tdColor: ['#D6F4FF', '#D6F4FF', '#D6F4FF', '#D6F4FF'],
tdBgColor: ['#0D2B3D', '#103B4C', '#14576B', '#187E99']
};
} else if (e === 'carousel') {
return { swiperOptions: {}, imageFit: 'contain', carouselImages: [] };
} else if (e === 'background') {
return { backgroundColor: '#fff', isBorder: true, borderColor: '#fff', backgroundImage: '' };
} else if (e === 'pagination') {
return { pageSizeField: 'pageSize', currentPageField: 'currentPage' };
return { pageSizeField: 'pageSize', currentPageField: 'pageNum' };
} else if (e === 'digitalFlop') {
return {
field: '', number: 1111, backgroundColor: 'rgba(180, 180, 180, 0.2)', isBorder: true, borderColor: '#fff'

Loading…
Cancel
Save