修改看板和打印设置

master
夜笙歌 4 days ago
parent 380d191ad3
commit 3a3ca999ba

@ -10,7 +10,7 @@ import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
NProgress.configure({ showSpinner: false });
const whiteList = ['/print', '/boardGenerate', '/boardView', '/boardConstruction', '/board1', '/board2', '/login', '/register', '/social-callback'];
const whiteList = ['/print', '/externalPrint', '/boardGenerate', '/boardView', '/boardConstruction', '/board1', '/board2', '/login', '/register', '/social-callback'];
router.beforeEach(async (to, from, next) => {
NProgress.start();

@ -26,6 +26,11 @@ import Layout from '@/layout/index.vue';
// 公共路由
export const constantRoutes: RouteRecordRaw[] = [
{
path: '/externalPrint',
hidden: true,
component: () => import('@/views/print/externalPrint.vue')
},
{
path: '/print',
hidden: true,

@ -109,12 +109,12 @@
<el-table :data="constructionDataForm.designDataFieldList" style="width: 100%">
<el-table-column label="字段名称" min-width="120">
<template #default="scope">
<el-input v-model="scope.row.name" style="width: 100%" />
<el-input v-model="scope.row.fieldOne" style="width: 100%" />
</template>
</el-table-column>
<el-table-column v-if="!isEasy" label="字段层级" min-width="120">
<template #default="scope">
<el-input v-model="scope.row.tier" style="width: 100%" />
<el-input v-model="scope.row.fieldTwo" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="备注" min-width="120">
@ -164,7 +164,7 @@ const comparisonTable = {
value: '值'
};
const isEasy = ref(false);
const isEasy = ref(true);
const loading = ref(false);
const paramsTableData = ref([]);
const selectForm = ref({
@ -210,6 +210,7 @@ const delData = () => {
constructionDataFormVisible.value = true;
};
const editDataSource = (e) => {
console.log(e);
constructionDataFormVisible.value = true;
constructionDataForm.value = e;
};
@ -243,8 +244,19 @@ const createData = () => {
if (!constructionDataForm.value.designDataFieldList) {
constructionDataForm.value.designDataFieldList = [];
}
let params = JSON.parse(JSON.stringify(constructionDataForm.value));
params.activeFlag = '1';
params.designDataFieldList = params.designDataFieldList.map(e => {
return {
fieldType: '2',
activeFlag: '1',
dataSourceId: params.dataSourceId,
fieldOne: e.fieldOne,
fieldTwo: e.fieldTwo
};
});
if (constructionDataForm.value.dataSourceId) {
editDataSourceApi(constructionDataForm.value).then(() => {
editDataSourceApi(params).then(() => {
constructionDataFormVisible.value = false;
ElMessage({
type: 'success',
@ -253,7 +265,7 @@ const createData = () => {
getList();
});
} else {
addDataSourceApi(constructionDataForm.value).then(() => {
addDataSourceApi(params).then(() => {
constructionDataFormVisible.value = false;
ElMessage({
type: 'success',
@ -284,18 +296,18 @@ const findTier = () => {
if (data?.data) {
Object.keys(data.data?.[0]).forEach(key => {
constructionDataForm.value.designDataFieldList.push({
name: key,
fieldOne: key,
remark: comparisonTable[key],
tier: `data,map%${key}`
fieldTwo: `data,map%${key}`
});
});
} else if (data?.rows) {
console.log(data?.rows);
Object.keys(data.rows?.[0]).forEach(key => {
constructionDataForm.value.designDataFieldList.push({
name: key,
fieldOne: key,
remark: comparisonTable[key],
tier: `rows,map%${key}`
fieldTwo: `rows,map%${key}`
});
});
} else {
@ -304,9 +316,9 @@ const findTier = () => {
if (!exclude.includes(key.toLowerCase())) {
if (typeof data[key] === 'string' || typeof data[key] === 'string') {
constructionDataForm.value.designDataFieldList.push({
name: key,
fieldOne: key,
remark: comparisonTable[key],
tier: `${key}`
fieldTwo: `${key}`
});
}
}

@ -210,6 +210,7 @@ const delData = () => {
constructionDataFormVisible.value = true;
};
const editDataSource = (e) => {
console.log(e);
constructionDataFormVisible.value = true;
constructionDataForm.value = e;
};

@ -501,7 +501,8 @@ onMounted(async () => {
return {
name: e.dataSourceName,
url: e.requestUrl,
method: e.requestMethod
method: e.requestMethod,
outputData: e.designDataFieldList
};
});
});

@ -109,6 +109,7 @@ const getOption = () => {
};
let xData = [props.inputData?.x1 || []];
let yData = [props.inputData?.y1 || []];
console.log(props.inputData);
let length = Math.min(...xData.map(e => e.length), ...yData.map(e => e.length));
let source = [['product', ...[props.data.options?.yNames?.[0] || '数量']]];
Array(length).fill(0).forEach((_, i) => {
@ -121,6 +122,7 @@ const getOption = () => {
});
source.push(item);
});
console.log(source);
return {
...chartOption,
dataset: {

@ -82,8 +82,9 @@ const parseData = (data, rule) => {
};
const getOutputData = () => {
let params = {};
(props.data.customData.inputData || []).forEach((item) => {
let params = props.inputData;
(Object.keys(props.inputData) || []).forEach((item) => {
params[item.name] = props.inputData[item.name];
});
(options.isD ? request : axios.request)({
@ -96,8 +97,9 @@ const getOutputData = () => {
let data = (options.isD ? res : res.data);
let output = {};
props.data.customData.outputData.forEach(item => {
output[item.name] = parseData(data, item.tier);
output[item.fieldOne] = parseData(data, item.fieldTwo);
});
console.log('output', output);
props.data.outputData = output;
}).catch(e => {
isErr.value = true;

@ -63,6 +63,8 @@ const convertData = () => {
res[item] = props.inputData[item];
}
});
console.log(props.inputData);
console.log(props.data.options.dataMap);
props.data.outputData = res;
};
watch(() => JSON.parse(JSON.stringify(props.inputData)), (obj1, obj2) => {

@ -124,7 +124,7 @@ const tool = () => {
};
export default tool;
export const options = {
isD: false, isJSON: (str) => {
isD: true, isJSON: (str) => {
if (typeof str === 'string') {
try {
JSON.parse(str);

@ -0,0 +1,261 @@
<template>
<div style="width: 100%;height: 100vh;overflow: hidden" title="预览" :close-on-press-escape="false"
:show-close="false">
<el-dropdown split-button type="primary" @click="printFun" @command="switchPrinter" style="margin-right: 8px;">
{{ printName() }}
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item :command="-1">导出PDF</el-dropdown-item>
<el-dropdown-item divided :command="0">本地打印</el-dropdown-item>
<el-dropdown-item :divided="k===0" :command="i.id" v-for=" (i,k) in printers">{{ i.name }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div id="printInfo" ref="printRef">
<div class="content" v-for=" pageData in pageDatas"
:style="{pageBreakAfter: 'always',width: cmToPx(pageWidth)+'px',height: cmToPx(pageHeight)+'px',marginBottom:'4px'}">
<div v-for="i in nodes" class="node" :style="{left:i.position?.x+'px',top: i.position?.y+'px'}">
<template v-if="i.type === 'text'">
<TextNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></TextNode>
</template>
<template v-if="i.type === 'image'">
<ImageNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></ImageNode>
</template>
<template v-if="i.type === 'barCode'">
<BarCodeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></BarCodeNode>
</template>
<template v-if="i.type === 'QRCode'">
<QRCodeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></QRCodeNode>
</template>
<template v-if="i.type === 'dateTime'">
<TimeNode v-bind="i" :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"></TimeNode>
</template>
<template v-if="i.type === 'select'">
<SelectNode :isView="true" :isPrint="isPrint" :pageData="pageData"
:pageSize="{width: cmToPx(pageWidth) ,height: cmToPx(pageHeight) }"
v-bind="i"></SelectNode>
</template>
</div>
</div>
</div>
<!-- <template #footer>-->
<span class="dialog-footer">
<!-- <el-button type="primary" @click="printFun"></el-button>-->
<!-- <el-button type="primary" v-print="printInfoObj"></el-button>-->
<el-button @click="closePrint"></el-button>
</span>
<!-- </template>-->
</div>
<div id="printArea" v-if="printPngList.length>0">
<div
v-for="(url, index) in printPngList"
:key="index"
class="print-page"
>
<img :src="url" class="print-image" />
</div>
</div>
</template>
<script setup>
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import { options } from '@/views/print/tool.js';
import TextNode from '@/views/print/nodes/textNode.vue';
import ImageNode from '@/views/print/nodes/image.vue';
import BarCodeNode from './nodes/barCodeNode.vue';
import QRCodeNode from './nodes/QRCodeNode.vue';
import TimeNode from './nodes/timeNode.vue';
import SelectNode from './nodes/selectNode.vue';
const printType = ref(0);
const printers = ref([
{
id: 1,
name: '网络打印机1'
},
{
id: 2,
name: '网络打印机2'
},
{
id: 3,
name: '网络打印机3'
}
]);
const printPngList = ref([]);
const isView = ref(true);
const isPrint = ref(false);
const printRef = ref();
const pageWidth = ref(21);
const pageHeight = ref(29.7);
const pageDatas = ref([{}]);
const { cmToPx } = options;
const nodes = ref([]);
onMounted(() => {
nodes.value = JSON.parse(localStorage.getItem('printNodes') || '[]');
});
const printInfoObj = {
id: 'printInfo',
preview: false, //
beforeOpenCallback(vue) {
console.log('触发打印工具打开前回调');
},
openCallback(vue) {
console.log('触发打印工具打开的回调');
},
closeCallback() {
console.log('触发关闭打印工具回调');
},
previewBeforeOpenCallback() {
console.log('触发预览前回调');
},
previewOpenCallback() {
console.log('触发预览的回调');
}
};
const switchPrinter = (e) => {
console.log(e);
printType.value = e;
};
const printFun = (e) => {
if (printType.value === -1) {
isPrint.value = true;
nextTick(() => {
const element = printRef.value;
let eles = element.querySelectorAll('.content');
const pros = [];
eles.forEach((ele, index) => {
pros.push(
html2canvas(ele).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF();
pdf.addImage(imgData, 'PNG', 0, 0);
pdf.save(`${new Date().getTime()}-${index}.pdf`);
})
);
});
Promise.all(pros).then((values) => {
isPrint.value = false;
});
});
} else if (printType.value === 0) {
isPrint.value = true;
printPngList.value = [];
nextTick(() => {
const element = printRef.value;
let eles = element.querySelectorAll('.content');
const pros = [];
eles.forEach((ele, index) => {
pros.push(
html2canvas(ele).then(canvas => {
const imgData = canvas.toDataURL('image/png');
printPngList.value.push(imgData);
})
);
});
Promise.all(pros).then((values) => {
window.print();
isPrint.value = false;
printPngList.value = [];
});
});
} else {
}
};
const closePrint = () => {
isView.value = false;
};
const openPrint = (pages, templateId) => {
isView.value = false;
nextTick(() => {
nodes.value = JSON.parse(localStorage.getItem('printNodes') || '[]');
isView.value = true;
let pageData = [];
if (Array.isArray(pages)) {
pageData = pages;
}
if (typeof pages !== 'object' || pages === null) {
pageData = [pages];
}
console.log(pageData);
pageDatas.value = pageData || [];
});
};
const printName = () => {
if (printType.value === -1) {
return '导出PDF';
} else if (printType.value === 0) {
return '本地打印';
} else {
let name = printers?.value?.find(e => e.id === printType?.value)?.name;
return name || '';
}
};
defineExpose({
openPrint
// closePrint
});
</script>
<style scoped>
.content {
position: relative;
overflow: hidden;
background-repeat: no-repeat;
background-size: 100% 100%;
border: 1px solid #ccc;
}
.node {
position: absolute;
}
</style>
<style>
.print-page {
page-break-after: always;
text-align: center;
padding: 20px;
background: white;
}
.print-image {
max-width: 100%;
height: auto;
}
/* 打印样式:仅显示图片区域 */
@media print {
body * {
visibility: hidden !important;
}
#printArea,
#printArea * {
visibility: visible !important;
}
#printArea {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.print-page {
page-break-after: always;
}
}
</style>

@ -567,7 +567,7 @@ const nodeChange = () => {
.content {
vertical-align: top;
display: inline-block;
width: calc(100vw - 300px - 300px - 16px - 16px);
width: calc(100% - 300px - 300px - 16px - 16px);
height: 100%;
margin-top: 8px;
border: 1px solid #ccc;

@ -53,7 +53,7 @@
</span>
</template>
</el-dialog>
<div id="printArea">
<div id="printArea" v-if="printPngList.length>0">
<div
v-for="(url, index) in printPngList"
:key="index"
@ -168,6 +168,7 @@ const printFun = (e) => {
Promise.all(pros).then((values) => {
window.print();
isPrint.value = false;
printPngList.value = [];
});
});
} else {

Loading…
Cancel
Save