Browse Source

打印:添加表单打印功能

master
han2015 1 week ago
parent
commit
1f1067e6c6
  1. 8
      package.json
  2. 352
      public/print-lock.css
  3. 22
      src/api/DesignForm/requestapi.ts
  4. 352
      src/assets/print-lock.css
  5. 91
      src/components/DesignForm/tableListPage/index.vue
  6. 240
      src/components/DesignForm/tableListPage/printHtmlRender.vue
  7. 5
      src/main.ts
  8. 2
      src/views/sysworkflow/codepage/createpage.vue
  9. 4
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/aiPage.vue
  10. 3
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/openAppFormPage.vue
  11. 277
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/panel.js
  12. 55
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js
  13. 331
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage2.vue
  14. 251
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPageCustom.vue
  15. 424
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/vue-plugin-provider.js
  16. 8
      src/views/sysworkflow/lowcodepage/appPage/createAppFormPage.vue
  17. 1
      src/views/sysworkflow/lowcodepage/appPage/index.vue
  18. 1
      src/views/sysworkflow/lowcodepage/appPage/releaseApp/index.vue

8
package.json

@ -44,6 +44,7 @@
"@dnd-kit/core": "^6.1.0",
"@element-plus/icons-vue": "^2.3.1",
"@onlyoffice/document-editor-vue": "^1.5.0",
"@sv-print/vue3": "^0.2.2",
"@tinymce/tinymce-vue": "^5.1.1",
"@vitejs/plugin-vue": "^4.2.3",
"@vueup/vue-quill": "^1.2.0",
@ -61,17 +62,20 @@
"element-resize-detector": "^1.2.4",
"font-awesome": "^4.7.0",
"html2canvas": "^1.4.1",
"jquery": "^3.7.1",
"install": "^0.13.0",
"js-beautify": "^1.14.8",
"js-md5": "^0.7.3",
"jsbarcode": "^3.12.1",
"jszip": "^3.10.1",
"mapv-three": "^1.0.18",
"md5": "^2.3.0",
"npm": "^11.4.2",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.0",
"pinia": "^2.1.6",
"province-city-china": "^8.5.8",
"qrcode": "^1.5.4",
"quill-image-resize-custom-module": "^4.1.7",
"quill-image-uploader": "^1.3.0",
"react-dnd-html5-backend": "^16.0.1",
@ -88,7 +92,7 @@
"vue-baidu-map-3x": "^1.0.35",
"vue-demi": "^0.14.10",
"vue-i18n": "9.2.2",
"vue-plugin-hiprint": "^0.0.59-beta4",
"vue-plugin-hiprint": "^0.0.60",
"vue-router": "^4.2.0",
"vue3-dnd": "^2.1.0",
"vue3-ruler-tool": "^0.0.1",

352
public/print-lock.css

@ -0,0 +1,352 @@
@media print {
body {
margin: 0px;
padding: 0px;
}
}
@page {
margin: 0;
}
.hiprint-printPaper * {
box-sizing: border-box;
-moz-box-sizing: border-box; /* Firefox */
-webkit-box-sizing: border-box; /* Safari */
}
.hiprint-printPaper *:focus {
outline: -webkit-focus-ring-color auto 0px;
}
.hiprint-printPaper {
position: relative;
padding: 0 0 0 0;
page-break-after: always;
-webkit-user-select: none; /* Chrome/Safari/Opera */
-moz-user-select: none; /* Firefox */
user-select: none;
overflow-x: hidden;
overflow: hidden;
}
.hiprint-printPaper .hiprint-printPaper-content {
position: relative;
}
/* 火狐浏览器打印 第一页过后 重叠问题 */
@-moz-document url-prefix() {
.hiprint-printPaper .hiprint-printPaper-content {
position: relative;
margin-top: 20px;
top: -20px
}
}
.hiprint-printPaper.design {
overflow: visible;
}
.hiprint-printTemplate .hiprint-printPanel {
page-break-after: always;
}
.hiprint-printPaper, hiprint-printPanel {
box-sizing: border-box;
border: 0px;
}
.hiprint-printPanel .hiprint-printPaper:last-child {
page-break-after: avoid;
}
.hiprint-printTemplate .hiprint-printPanel:last-child {
page-break-after: avoid;
}
.hiprint-printPaper .hideheaderLinetarget {
border-top: 0px dashed rgb(201, 190, 190) !important;
}
.hiprint-printPaper .hidefooterLinetarget {
border-top: 0px dashed rgb(201, 190, 190) !important;
}
.hiprint-printPaper.design {
border: 1px dashed rgba(170, 170, 170, 0.7);
}
.design .hiprint-printElement-table-content, .design .hiprint-printElement-longText-content {
overflow: hidden;
box-sizing: border-box;
}
.design .resize-panel {
box-sizing: border-box;
border: 1px dotted;
}
.hiprint-printElement-text {
background-color: transparent;
background-repeat: repeat;
padding: 0 0 0 0;
border: 0.75pt none rgb(0, 0, 0);
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
line-height: 9.75pt;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
}
.design .hiprint-printElement-text-content {
border: 1px dashed rgb(206, 188, 188);
box-sizing: border-box;
}
.hiprint-printElement-longText {
background-color: transparent;
background-repeat: repeat;
border: 0.75pt none rgb(0, 0, 0);
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
line-height: 9.75pt;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
/*white-space: pre-wrap*/
}
.hiprint-printElement-table {
background-color: transparent;
background-repeat: repeat;
color: rgb(0, 0, 0);
border-color: rgb(0, 0, 0);
border-style: none;
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
padding: 0 0 0 0;
box-sizing: border-box;
line-height: 9.75pt;
}
.hiprint-printElement-table thead {
background: #e8e8e8;
font-weight: 700;
}
table.hiprint-printElement-tableTarget {
width: 100%;
}
.hiprint-printElement-tableTarget, .hiprint-printElement-tableTarget tr, .hiprint-printElement-tableTarget td {
border-color: rgb(0, 0, 0);
/*border-style: none;*/
/*border: 1px solid rgb(0, 0, 0);*/
font-weight: normal;
direction: ltr;
padding-bottom: 0pt;
padding-left: 4pt;
padding-right: 4pt;
padding-top: 0pt;
text-decoration: none;
vertical-align: middle;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
/*line-height: 9.75pt;
font-size: 9pt;*/
}
.hiprint-printElement-tableTarget-border-all {
border: 1px solid;
}
.hiprint-printElement-tableTarget-border-none {
border: 0px solid;
}
.hiprint-printElement-tableTarget-border-lr {
border-left: 1px solid;
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-left {
border-left: 1px solid;
}
.hiprint-printElement-tableTarget-border-right {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-tb {
border-top: 1px solid;
border-bottom: 1px solid;
}
.hiprint-printElement-tableTarget-border-top {
border-top: 1px solid;
}
.hiprint-printElement-tableTarget-border-bottom {
border-bottom: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-none td {
border: 0px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:not(:nth-last-child(-n+2)) {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:not(last-child) {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:last-child {
border-left: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:last-child:first-child {
border-left: none;
}
/*.hiprint-printElement-tableTarget tr,*/
.hiprint-printElement-tableTarget td {
height: 18pt;
}
.hiprint-printPaper .hiprint-paperNumber {
font-size: 9pt;
}
.design .hiprint-printElement-table-handle {
position: absolute;
height: 21pt;
width: 21pt;
background: red;
z-index: 1;
}
.hiprint-printPaper .hiprint-paperNumber-disabled {
float: right !important;
right: 0 !important;
color: gainsboro !important;
}
.hiprint-printElement-vline, .hiprint-printElement-hline {
border: 0px none rgb(0, 0, 0);
}
.hiprint-printElement-vline {
border-left: 0.75pt solid #000;
border-right: 0px none rgb(0, 0, 0) !important;
border-bottom: 0px none rgb(0, 0, 0) !important;
border-top: 0px none rgb(0, 0, 0) !important;
}
.hiprint-printElement-hline {
border-top: 0.75pt solid #000;
border-right: 0px none rgb(0, 0, 0) !important;
border-bottom: 0px none rgb(0, 0, 0) !important;
border-left: 0px none rgb(0, 0, 0) !important;
}
.hiprint-printElement-oval, .hiprint-printElement-rect {
border: 0.75pt solid #000;
}
.hiprint-text-content-middle {
}
.hiprint-text-content-middle > div {
display: grid;
align-items: center;
}
.hiprint-text-content-bottom {
}
.hiprint-text-content-bottom > div {
display: grid;
align-items: flex-end;
}
.hiprint-text-content-wrap {
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-nowrap {
white-space: nowrap;
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-clip {
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/*hi-grid-row */
.hi-grid-row {
position: relative;
height: auto;
margin-right: 0;
margin-left: 0;
zoom: 1;
display: block;
box-sizing: border-box;
}
.hi-grid-row::after, .hi-grid-row::before {
display: table;
content: '';
box-sizing: border-box;
}
.hi-grid-col {
display: block;
box-sizing: border-box;
position: relative;
float: left;
flex: 0 0 auto;
}
.table-grid-row {
margin-left: -0pt;
margin-right: -0pt;
}
.tableGridColumnsGutterRow {
padding-left: 0pt;
padding-right: 0pt;
}
.hiprint-gridColumnsFooter {
text-align: left;
clear: both;
}

22
src/api/DesignForm/requestapi.ts

@ -633,3 +633,25 @@ export function gainDataStorceAllField(data: any) {
data: data
});
}
//获取有源数据表字段
/*
VersionId string `json:"versionid"`
FormKey string `json:"formkey"`
*/
export function getPrintTemplate(data: any) {
return request({
url: '/printer/customer_form/getPrintTemplate',
method: 'post',
data: data
});
}
//获取有源数据表字段
export function savePrintTemplate(data: any) {
return request({
url: '/printer/customer_form/savePrintTemplate',
method: 'post',
data: data
});
}

352
src/assets/print-lock.css

@ -0,0 +1,352 @@
@media print {
body {
margin: 0px;
padding: 0px;
}
}
@page {
margin: 0;
}
.hiprint-printPaper * {
box-sizing: border-box;
-moz-box-sizing: border-box; /* Firefox */
-webkit-box-sizing: border-box; /* Safari */
}
.hiprint-printPaper *:focus {
outline: -webkit-focus-ring-color auto 0px;
}
.hiprint-printPaper {
position: relative;
padding: 0 0 0 0;
page-break-after: always;
-webkit-user-select: none; /* Chrome/Safari/Opera */
-moz-user-select: none; /* Firefox */
user-select: none;
overflow-x: hidden;
overflow: hidden;
}
.hiprint-printPaper .hiprint-printPaper-content {
position: relative;
}
/* 火狐浏览器打印 第一页过后 重叠问题 */
@-moz-document url-prefix() {
.hiprint-printPaper .hiprint-printPaper-content {
position: relative;
margin-top: 20px;
top: -20px
}
}
.hiprint-printPaper.design {
overflow: visible;
}
.hiprint-printTemplate .hiprint-printPanel {
page-break-after: always;
}
.hiprint-printPaper, hiprint-printPanel {
box-sizing: border-box;
border: 0px;
}
.hiprint-printPanel .hiprint-printPaper:last-child {
page-break-after: avoid;
}
.hiprint-printTemplate .hiprint-printPanel:last-child {
page-break-after: avoid;
}
.hiprint-printPaper .hideheaderLinetarget {
border-top: 0px dashed rgb(201, 190, 190) !important;
}
.hiprint-printPaper .hidefooterLinetarget {
border-top: 0px dashed rgb(201, 190, 190) !important;
}
.hiprint-printPaper.design {
border: 1px dashed rgba(170, 170, 170, 0.7);
}
.design .hiprint-printElement-table-content, .design .hiprint-printElement-longText-content {
overflow: hidden;
box-sizing: border-box;
}
.design .resize-panel {
box-sizing: border-box;
border: 1px dotted;
}
.hiprint-printElement-text {
background-color: transparent;
background-repeat: repeat;
padding: 0 0 0 0;
border: 0.75pt none rgb(0, 0, 0);
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
line-height: 9.75pt;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
}
.design .hiprint-printElement-text-content {
border: 1px dashed rgb(206, 188, 188);
box-sizing: border-box;
}
.hiprint-printElement-longText {
background-color: transparent;
background-repeat: repeat;
border: 0.75pt none rgb(0, 0, 0);
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
line-height: 9.75pt;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
/*white-space: pre-wrap*/
}
.hiprint-printElement-table {
background-color: transparent;
background-repeat: repeat;
color: rgb(0, 0, 0);
border-color: rgb(0, 0, 0);
border-style: none;
direction: ltr;
font-family: 'SimSun';
font-size: 9pt;
font-style: normal;
font-weight: normal;
padding-bottom: 0pt;
padding-left: 0pt;
padding-right: 0pt;
padding-top: 0pt;
text-align: left;
text-decoration: none;
padding: 0 0 0 0;
box-sizing: border-box;
line-height: 9.75pt;
}
.hiprint-printElement-table thead {
background: #e8e8e8;
font-weight: 700;
}
table.hiprint-printElement-tableTarget {
width: 100%;
}
.hiprint-printElement-tableTarget, .hiprint-printElement-tableTarget tr, .hiprint-printElement-tableTarget td {
border-color: rgb(0, 0, 0);
/*border-style: none;*/
/*border: 1px solid rgb(0, 0, 0);*/
font-weight: normal;
direction: ltr;
padding-bottom: 0pt;
padding-left: 4pt;
padding-right: 4pt;
padding-top: 0pt;
text-decoration: none;
vertical-align: middle;
box-sizing: border-box;
word-wrap: break-word;
word-break: break-all;
/*line-height: 9.75pt;
font-size: 9pt;*/
}
.hiprint-printElement-tableTarget-border-all {
border: 1px solid;
}
.hiprint-printElement-tableTarget-border-none {
border: 0px solid;
}
.hiprint-printElement-tableTarget-border-lr {
border-left: 1px solid;
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-left {
border-left: 1px solid;
}
.hiprint-printElement-tableTarget-border-right {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-tb {
border-top: 1px solid;
border-bottom: 1px solid;
}
.hiprint-printElement-tableTarget-border-top {
border-top: 1px solid;
}
.hiprint-printElement-tableTarget-border-bottom {
border-bottom: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-none td {
border: 0px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:not(:nth-last-child(-n+2)) {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:not(last-child) {
border-right: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:last-child {
border-left: 1px solid;
}
.hiprint-printElement-tableTarget-border-td-all td:last-child:first-child {
border-left: none;
}
/*.hiprint-printElement-tableTarget tr,*/
.hiprint-printElement-tableTarget td {
height: 18pt;
}
.hiprint-printPaper .hiprint-paperNumber {
font-size: 9pt;
}
.design .hiprint-printElement-table-handle {
position: absolute;
height: 21pt;
width: 21pt;
background: red;
z-index: 1;
}
.hiprint-printPaper .hiprint-paperNumber-disabled {
float: right !important;
right: 0 !important;
color: gainsboro !important;
}
.hiprint-printElement-vline, .hiprint-printElement-hline {
border: 0px none rgb(0, 0, 0);
}
.hiprint-printElement-vline {
border-left: 0.75pt solid #000;
border-right: 0px none rgb(0, 0, 0) !important;
border-bottom: 0px none rgb(0, 0, 0) !important;
border-top: 0px none rgb(0, 0, 0) !important;
}
.hiprint-printElement-hline {
border-top: 0.75pt solid #000;
border-right: 0px none rgb(0, 0, 0) !important;
border-bottom: 0px none rgb(0, 0, 0) !important;
border-left: 0px none rgb(0, 0, 0) !important;
}
.hiprint-printElement-oval, .hiprint-printElement-rect {
border: 0.75pt solid #000;
}
.hiprint-text-content-middle {
}
.hiprint-text-content-middle > div {
display: grid;
align-items: center;
}
.hiprint-text-content-bottom {
}
.hiprint-text-content-bottom > div {
display: grid;
align-items: flex-end;
}
.hiprint-text-content-wrap {
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-nowrap {
white-space: nowrap;
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-clip {
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
.hiprint-text-content-wrap .hiprint-text-content-wrap-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/*hi-grid-row */
.hi-grid-row {
position: relative;
height: auto;
margin-right: 0;
margin-left: 0;
zoom: 1;
display: block;
box-sizing: border-box;
}
.hi-grid-row::after, .hi-grid-row::before {
display: table;
content: '';
box-sizing: border-box;
}
.hi-grid-col {
display: block;
box-sizing: border-box;
position: relative;
float: left;
flex: 0 0 auto;
}
.table-grid-row {
margin-left: -0pt;
margin-right: -0pt;
}
.tableGridColumnsGutterRow {
padding-left: 0pt;
padding-right: 0pt;
}
.hiprint-gridColumnsFooter {
text-align: left;
clear: both;
}

91
src/components/DesignForm/tableListPage/index.vue

@ -28,7 +28,7 @@ import {
checkboxUnit,
orgDeptUnit,
} from "@/api/DesignForm/fieldUnit";
import type { FormInstance, FormRules } from "element-plus";
import type { FormInstance, FormRules,ElButton } from "element-plus";
import { gainFormPageListCont } from "@/api/DesignForm/requestapi";
import { Picture, InfoFilled, QuestionFilled } from "@element-plus/icons-vue";
import request from "@/utils/request";
@ -38,6 +38,10 @@ import { ElLoading, ElMessage, ElNotification } from "element-plus";
import { softDeletion, retractRunWorkFlow, recalSendMsg } from "@/api/taskapi/management";
import { echatsViews } from "@/api/DesignForm/types";
import { formatNumber } from "@/api/DesignForm/utils";
import { Ref } from "vue";
import printHtmlRender from './printHtmlRender.vue'
import {fieldTree} from './printHtmlRender.vue'
import {printElement} from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js"
//
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
import TableFlow from "@/views/sysworkflow/lowcodepage/pageFlow/tableFlow.vue";
@ -49,6 +53,8 @@ import CalendarPage from "@/components/DesignForm/app/calendar/calendar1/calenda
import SearchSelect from "@/components/DesignForm/app/calendar/selectSearch.vue";
import ContainerPath from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/echatesUnit/container.vue";
import SeeContChart from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/echatesUnit/seeContChart.vue";
import {getPrintTemplate} from '@/api/DesignForm/requestapi'
import { display } from "html2canvas/dist/types/css/property-descriptors/display";
const props = withDefaults(
defineProps<{
@ -69,6 +75,7 @@ const props = withDefaults(
delKey?: string; //
lookPageIsShow?: boolean;
versionid?: string;
formKey?:string;
versiontitle?: string;
viewPage?: viewPageType;
formBasicConfig?: any;
@ -1335,6 +1342,69 @@ const lookPageInfo = (val: any) => {
drawerWith.value = container.value?.clientWidth;
lookPageInfoIsShow.value = true;
};
const printRenderMode = ref(false);
// Explicitly type as Ref<any[]>
const printRenderTree: Ref<any[]> = ref([]);
const printPage = async (row: any) => {
let data:any[]=[]
let title:string="表单";
await getPrintTemplate({"versionid":props.versionid,"formkey":props.formKey}).then(resp=>{
title=resp.data.title
data=JSON.parse(resp.data.formtemplatejson)
})
data.forEach(node=>{
deepLoopForm(node,row)
})
printRenderTree.value=data
printRenderMode.value = true;
ElMessageBox({
message: () => h('div',{style:{ width:'1000px',display:'flex','flex-direction':'column'}},[
h(ElButton, {
type:"primary",
style: "margin:10px 10px 5px auto;",
onClick: () => {
printElement("printContainer")
}
},'打印表单'),
h('div',{style:{ border: '1px solid black', width: 'fit-content', margin: '5px'}},[
h(printHtmlRender, {
name:title,
fieldTree:printRenderTree.value,
formData:row
})
])
]),
showConfirmButton:false,
customStyle: { '--el-messagebox-width':'1100px',padding:'10px'},
}).then(() => {
})
};
function deepLoopForm(node:fieldTree, row: Record<string, any>){
if(Array.isArray(node)){
node.forEach(item=>{deepLoopForm(item,row)})
return
}
if(node.field!=""){
let rnode:Object;
if (row.hasOwnProperty(node.field!)){//
if (node.type=="table" || node.type=="tabs"){
node.data=row[node.field!]
}else{
node.field=row[node.field!]
}
}
}
}
/**
@ 作者: 秦东
@ 时间: 2024-04-05 11:29:50
@ -1946,7 +2016,6 @@ const isObject = (obj: any) => {
align="center"
>
<template v-if="item.help" #header="scope">
{{ scope.column.label }}
<tooltip :content="item.help" />
</template>
</el-table-column>
@ -2005,6 +2074,20 @@ const isObject = (obj: any) => {
/>
</el-tooltip>
<el-tooltip
class="box-item"
effect="dark"
content="打印表单"
placement="top-end"
>
<el-button
@click="printPage(scope.row)"
type="primary"
size="small"
class="fa fa-print"
/>
</el-tooltip>
<el-popconfirm
v-if="scope.row.retract_true"
confirm-button-text="确定"
@ -2108,7 +2191,6 @@ const isObject = (obj: any) => {
<template v-if="item.pattern == 'table'" v-for="sunItem in item.children">
<el-table-column v-if="sunItem.fieldClass == ''" :prop="sunItem.field" :label="sunItem.label" header-align="center" align="center" :min-width="readerColumnSun(sunItem)">
<template #default="scopeChilder">
<div v-html="tableChildren(sunItem.field,scopeChilder.row[item.field])"></div>
</template>
</el-table-column>
@ -2334,7 +2416,6 @@ const isObject = (obj: any) => {
@getPageData="getPageData"
@optionsValue4Get4="optionsValue4Get4"
/>
<FormPageCont
v-model:is-show="asflookPageInfoIsShow"
:drawer-with="drawerWith"
@ -2344,6 +2425,7 @@ const isObject = (obj: any) => {
@getPageData="getPageData"
@optionsValue4Get4="optionsValue4Get4"
/>
<TableFlow
v-model:isopen="openTaskDrawer"
:versionid="props.versionid"
@ -2455,7 +2537,6 @@ const isObject = (obj: any) => {
</div>
</template>
</el-dialog>
<el-dialog
v-model="asfShowDetailsFlag"
title="关联表单详情查看"

240
src/components/DesignForm/tableListPage/printHtmlRender.vue

@ -0,0 +1,240 @@
<script lang="ts" setup>
export interface fieldTree{
field?:string;
name?:string;
type:string;
checked:number;
data?:[];
child?:fieldTree[]
}
const props = withDefaults(defineProps<{
name:string,
fieldTree:fieldTree[],
formData?:any
}>(),{})
</script>
<template style="width: 210mm;height: 297mm;">
<div id="printContainer" >
<h3>{{props.name}}</h3>
<div v-for="group in props.fieldTree">
<div v-if="Array.isArray(group)">
<el-descriptions
class="margin-top"
:column="2"
border
>
<template v-for="item in group" >
<el-descriptions-item v-if="item.checked!=2">
<template #label>
<div class="cell-item">
{{item.name}}
</div>
</template>
{{item.field}}
</el-descriptions-item>
</template>
</el-descriptions>
</div>
<div v-else-if="group.type=='divider'" class="title" v-if="group.checked!=2">{{ group.name }}</div>
<div v-else-if="group.type=='textarea'" class="section" v-if="group.checked!=2">
<h5>{{ group.name }}</h5>
<div class="text_area">{{ group.field }}</div>
</div>
<div v-else-if="group.type=='table'" class="section_table" v-if="group.checked!=2">
<h5>{{ group.name }}</h5>
<el-table class="table" :data="group.data" border style="width: 100%;margin:5px 10px 10px 10px">
<template v-for="child in group.child">
<el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" />
</template>
</el-table>
</div>
<div v-else-if="group.type=='tabs'" class="section_tabs" v-if="group.checked!=2">
<h5>{{ group.name }}</h5>
<div v-for="tabs in group.child" class="tabs_item">
<div v-if="Array.isArray(tabs)">
<el-descriptions
class="margin-top"
:column="2"
border
>
<template v-for="item in group" >
<el-descriptions-item v-if="item.checked!=2">
<template #label>
<div class="cell-item">
{{item.name}}
</div>
</template>
{{item.field}}
</el-descriptions-item>
</template>
</el-descriptions>
</div>
<div v-else-if="tabs.type=='divider'" class="title" v-if="tabs.checked!=2"
style="font-size: 12px; margin-top: 20px;">{{ tabs.name }}</div>
<div v-else-if="tabs.type=='textarea'" class="section" v-if="tabs.checked!=2">
<h5>{{ tabs.name }}</h5>
<div class="text_area">{{ tabs.field }}</div>
</div>
<div v-else-if="tabs.type=='table'" class="section" v-if="tabs.checked!=2">
<h5>{{ tabs.name }}</h5>
<el-table class="table" border style="width: 100%;">
<template v-for="child in tabs.child">
<el-table-column :prop="child.field" :label="child.name" v-if="child.checked!=2" />
</template>
</el-table>
</div>
<div v-else class="cell_box" v-if="tabs.checked!=2">
<span class="box_name">
{{tabs.name}}
</span>
<span class="content">{{tabs.field}}</span>
</div>
</div>
</div>
<div v-else v-if="group.checked!=2">{{ group }}</div>
</div>
</div>
</template>
<style lang="scss" scoped>
#printContainer{
width: 210mm;
height: 297mm;
padding: 30px 0px 15px 0px;
text-align: center;
display: flex;
flex-direction: column;
overflow-y: scroll;
scrollbar-width: none;
}
h3{
width: 100%;
font-size: 25px;
font-weight: bold;
}
h5{
font-weight: bold;
width: 100%;
margin: 5px;
}
.title{
margin-left:10px;
text-align: left;
font-size: 15px;
font-weight: bold;
}
.el-descriptions {
margin-top: 20px;
}
.cell-item {
display: flex;
align-items: center;
}
.margin-top {
margin: 10px;
}
.section_title{
width:100%
}
.section_table{
width: 96%;
}
.normal_cell,.normal_cell_field{
width: 23%;
height: 20px;
background-color: #f5f7fa;
}
.normal_cell_field{
background-color: white;
}
.section{
display: flex;
flex-direction: column;
}
.section_tabs{
margin: 10px;
display: flex;
flex-wrap: wrap;
}
.text_area{
border: 1px solid rgb(182, 181, 181);
border-radius: 3px;
min-height: 40px;
margin: 5px 10px 10px 10px;
}
//////////////
.tabs_item {
display: inline-flex;
min-height: 40px;
min-width: 50%; /* 默认最小宽度 */
/* 默认情况:没有 title/section 时宽度 50% */
width: 50%;
.section{
width: 100%;
}
}
/* 当直接子元素包含 title 或 section 时,宽度变为 100% */
.tabs_item:has(> .title),
.tabs_item:has(> .section) {
width: 100%;
}
/* 原有样式(稍作优化) */
.cell_box {
width: 100%;
border: 1px solid #ebeef5;
display: inline-flex;
.box_name {
background-color: #f5f7fa;
padding: 8px 11px;
width: 50%;
text-wrap: wrap;
text-overflow: ellipsis;
max-height: 80px;
overflow: hidden; /* 配合 ellipsis 需要 */
}
.content {
padding: 8px 11px;
width: 50%;
text-wrap: wrap;
word-break: break-all;
}
}
</style>
<style>
#printContainer table{
display: block;
border: 0px solid;
border-spacing: 1px;
border-collapse: collapse;
th{
background-color: #e5e5e5;
border: 1px solid;
min-width: 180px;
}
td{
border: 1px solid;
min-width: 180px;
}
}
</style>

5
src/main.ts

@ -30,6 +30,7 @@ import * as pinia from './store/index'
import SketchRule from 'vue3-sketch-ruler'
import 'vue3-sketch-ruler/lib/style.css'
import {hiPrintPlugin} from "vue-plugin-hiprint"
@ -50,8 +51,10 @@ app.directive('focus', {
}
});
hiPrintPlugin.disAutoConnect();
app.use(router).use(i18n).use(ComComponents).use(ComWidget).use(ElementPlus, {
locale: zhCn
}).use(AKDesign).use(pinia.store).mount('#app');
}).use(hiPrintPlugin).use(AKDesign).use(pinia.store).mount('#app');

2
src/views/sysworkflow/codepage/createpage.vue

@ -411,7 +411,7 @@ const toggleExpand = (group: Menu) => {
</el-aside>
<!-- 主要内容区域 -->
<el-main>
表单预览
表单预览++
</el-main>
</el-container>
</div>

4
src/views/sysworkflow/lowcodepage/appPage/appPageForm/aiPage.vue

@ -141,9 +141,7 @@ const sendPickTracn = () => {
</el-main>
<el-aside width="400px" class="asideBox">
<el-divider content-position="left">AI触发条件设置</el-divider>
<el-button type="warning" class="aiButs" @click="sendPickTracn"
>发布AI触发条件</el-button
>
<el-button type="warning" class="aiButs" @click="sendPickTracn">发布AI触发条件</el-button>
<el-scrollbar class="aiBox">
<el-card
v-for="(item, index) in props.state.formData.aiConfig"

3
src/views/sysworkflow/lowcodepage/appPage/appPageForm/openAppFormPage.vue

@ -540,6 +540,7 @@ defineExpose({
:config="stateList.config"
:form-id="stateForm.formId"
:versionid="versionId"
:form-key="props.formKey"
:versiontitle="versionTitle"
v-model:look-page-is-show="lookPageIsShow"
:viewPage="stateList.view"
@ -582,7 +583,7 @@ defineExpose({
<el-row v-else>
<el-col :span="24" class="pageBox">
<el-card class="tispMsg" shadow="always">
欢迎使用 {{ props.appCont.appName }}<br />
欢迎使用+++ {{ props.appCont.appName }}<br />
<div class="demo-image__error">
<el-image :src="props.appCont.appSvg" fit="fit">
<template #error>

277
src/views/sysworkflow/lowcodepage/appPage/appPageForm/panel.js

@ -0,0 +1,277 @@
export default {
"panels": [{
"index": 0,
"height": 297,
"width": 210,
"paperHeader": 49.5,
"paperFooter": 780,
"printElements": [{
"options": {
"left": 175.5,
"top": 10.5,
"height": 27,
"width": 259,
"title": "HiPrint自定义模块打印插件",
"fontSize": 19,
"fontWeight": "600",
"textAlign": "center",
"lineHeight": 26
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 27, "height": 13, "width": 52, "title": "页眉线", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 25.5, "top": 57, "height": 705, "width": 9, "fixed": true, "borderStyle": "dotted"},
"printElementType": {"type": "vline"}
}, {
"options": {"left": 60, "top": 61.5, "height": 48, "width": 87, "src": ""},
"printElementType": {"title": "图片", "type": "image"}
}, {
"options": {
"left": 153,
"top": 64.5,
"height": 39,
"width": 276,
"title": "二维码以及条形码均采用svg格式打印。不同打印机打印不会造成失真。图片打印:不同DPI打印可能会导致失真,",
"fontFamily": "微软雅黑",
"textAlign": "center",
"lineHeight": 18
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 457.5,
"top": 79.5,
"height": 13,
"width": 120,
"title": "姓名",
"field": "name",
"testData": "古力娜扎",
"color": "#f00808",
"textDecoration": "underline",
"textAlign": "center"
}, "printElementType": {"title": "文本", "type": "text"}
}, {
"options": {
"left": 483,
"top": 124.5,
"height": 43,
"width": 51,
"title": "123456789",
"textType": "qrcode"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 285,
"top": 130.5,
"height": 34,
"width": 175,
"title": "123456789",
"fontFamily": "微软雅黑",
"textAlign": "center",
"textType": "barcode"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 60,
"top": 132,
"height": 19,
"width": 213,
"title": "所有打印元素都可已拖拽的方式来改变元素大小",
"fontFamily": "微软雅黑",
"textAlign": "center",
"lineHeight": 18
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 153,
"top": 189,
"height": 13,
"width": 238,
"title": "单击元素,右侧可自定义元素属性",
"textAlign": "center",
"fontFamily": "微软雅黑"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 190.5, "height": 13, "width": 51, "title": "横线", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 415.5,
"top": 190.5,
"height": 13,
"width": 164,
"title": "可以配置各属性的默认值",
"textAlign": "center",
"fontFamily": "微软雅黑"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 214.5, "height": 10, "width": 475.5},
"printElementType": {"title": "横线", "type": "hline"}
}, {
"options": {
"left": 235.5,
"top": 220.5,
"height": 32,
"width": 342,
"title": "自定义表格:用户可左键选中表头,右键查看可操作项,操作类似Excel,双击表头单元格可进行编辑。内容:title#field",
"fontFamily": "微软雅黑",
"textAlign": "center",
"lineHeight": 15
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 156,
"top": 265.5,
"height": 13,
"width": 94,
"title": "表头列大小可拖动",
"fontFamily": "微软雅黑",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 60,
"top": 265.5,
"height": 13,
"width": 90,
"title": "红色区域可拖动",
"fontFamily": "微软雅黑",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 60,
"top": 285,
"height": 44,
"width": 511.5,
"field": "table",
"fields": [{"text":'id',"field":'id'},{"text":'姓名',"field":'name'},{"text":'性别',"field":'gender'},{"text":'数量',"field":'count'}],
"columns": [[{"width": 85.25, "colspan": 1, "rowspan": 1, "checked": true}, {
"width": 85.25,
"colspan": 1,
"rowspan": 1,
"checked": true
}, {
"title": "姓名",
"field": "name",
"width": 85.25,
"align": "center",
"colspan": 1,
"rowspan": 1,
"checked": true,
}, {"width": 85.25, "colspan": 1, "rowspan": 1, "checked": true}, {
"width": 85.25,
"colspan": 1,
"rowspan": 1,
"checked": true
}, {"width": 85.25, "colspan": 1, "rowspan": 1, "checked": true}]]
}, "printElementType": {
"title": "表格", "type": "table",
editable:true,
columnDisplayEditable: true,//列显示是否能编辑
columnDisplayIndexEditable: true,//列顺序显示是否能编辑
columnTitleEditable: true,//列标题是否能编辑
columnResizable: true, //列宽是否能调整
columnAlignEditable: true,//列对齐是否调整
}
}, {
"options": {
"left": 21,
"top": 346.5,
"height": 61.5,
"width": 15,
"title": "装订线",
"lineHeight": 18,
"fixed": true,
"contentPaddingTop": 3.75,
"backgroundColor": "#ffffff"
}, "printElementType": {"type": "text"}
}, {
"options": {
"left": 225,
"top": 349.5,
"height": 13,
"width": 346.5,
"title": "自定义模块:主要为开发人员设计,能够快速,简单,实现自己功能",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 370.5, "height": 18, "width": 79, "title": "配置项表格", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 225,
"top": 385.5,
"height": 38,
"width": 346.5,
"title": "配置模块:主要为客户使用,开发人员可以配置属性,字段,标题等,客户直接使用,配置模块请参考实例2",
"fontFamily": "微软雅黑",
"lineHeight": 15,
"textAlign": "center",
"color": "#d93838"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 60,
"top": 487.5,
"height": 13,
"width": 123,
"title": "长文本会自动分页",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 507, "height": 40, "width": 511.5, "field": "longText"},
"printElementType": {"title": "长文", "type": "longText"}
}, {
"options": {"left": 475.5, "top": 565.5, "height": 100, "width": 100},
"printElementType": {"title": "矩形", "type": "rect"}
}, {
"options": {"left": 174, "top": 568.5, "height": 13, "width": 90, "title": "竖线", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 60, "top": 574.5, "height": 100, "width": 10},
"printElementType": {"title": "竖线", "type": "vline"}
}, {
"options": {"left": 210, "top": 604.5, "height": 13, "width": 120, "title": "横线", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 130.5, "top": 625.5, "height": 10, "width": 277},
"printElementType": {"title": "横线", "type": "hline"}
}, {
"options": {
"left": 364.5,
"top": 649.5,
"height": 13,
"width": 101,
"title": "矩形",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 525, "top": 784.5, "height": 13, "width": 63, "title": "页尾线", "textAlign": "center"},
"printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {"left": 12, "top": 786, "height": 49, "width": 49},
"printElementType": {"title": "html", "type": "html"}
}, {
"options": {
"left": 75,
"top": 790.5,
"height": 13,
"width": 137,
"title": "红色原型是自动定义的Html",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}, {
"options": {
"left": 334.5,
"top": 810,
"height": 13,
"width": 205,
"title": "页眉线已上。页尾下以下每页都会重复打印",
"textAlign": "center"
}, "printElementType": {"title": "自定义文本", "type": "text"}
}],
"paperNumberLeft": 565.5,
"paperNumberTop": 819
}]
}

55
src/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js

@ -0,0 +1,55 @@
export function printElement(elementId) {
const element = document.getElementById(elementId);
if (!element) {
console.error('元素未找到');
return;
}
// 克隆元素,避免影响原页面
const printContent = element.cloneNode(true);
// 创建隐藏iframe
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
// 写入样式和内容
iframeDoc.open();
iframeDoc.write(`
<html>
<head>
<title>打印</title>
<style>
/* 打印优化样式 */
body { margin: 20px; font-size: 14px; }
@media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
/* 复制原页面样式 */
${Array.from(document.styleSheets)
.map(sheet => {
try {
return Array.from(sheet.cssRules).map(rule => rule.cssText).join('\n');
} catch (e) {
return '';
}
})
.join('\n')}
</style>
</head>
<body style="background:white !important;">
${printContent.outerHTML}
</body>
</html>
`);
iframeDoc.close();
// 触发打印
iframe.onload = function() {
iframe.contentWindow.print();
// 延迟移除iframe
setTimeout(() => document.body.removeChild(iframe), 1000);
};
}

331
src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage2.vue

@ -0,0 +1,331 @@
<!--
@ 作者: han2015
@ 时间: 2025-03-24 15:32:40
@ 备注: 打印模版设计
-->
<script lang="ts" setup>
import { ref, onMounted,toRaw} from 'vue';
import {getPrintTemplate,savePrintTemplate} from '@/api/DesignForm/requestapi'
import printHtmlRender from '@/components/DesignForm/tableListPage/printHtmlRender.vue'
import {fieldTree} from '@/components/DesignForm/tableListPage/printHtmlRender.vue'
import { fieldList } from '@/views/sysworkflow/codepage/mathFunction';
import { extend } from 'dayjs';
interface fieldTreeEx extends fieldTree{
unitName?:string;
list?:fieldTreeEx[];
columns?:fieldTreeEx[];
}
const printMode=ref("")
const tabPosition = ref<TabsInstance['tabPosition']>('left')
const fieldTreeData=ref<fieldTree[]>([])
const htmlRenderData=ref<any[]>([])
let defaultCheckList:string[]=[]
const treeLoaded=ref(false) //
const fieldTreeRef=ref()
const props = defineProps({
appCont: {
type: Object,
default() {
return {};
},
},
formKey: {
type: String,
default: "",
},
groupKey: {
type: String,
default: "",
},
menuId: {
type: String,
default: "",
},
appPageKey: {
type: String,
default: "",
},
formVersion: {
type: String,
default: "",
},
state: {
type: Object,
default() {
return {};
},
},
});
function safeStringify(obj, space = 2) {
return JSON.stringify(obj, (key, value) => {
// toRaw Proxy
return toRaw(value) ?? value; // ProxytoRaw undefined ??
}, space);
}
//
function onSaveTreeData(){
let str:string=safeStringify(htmlRenderData.value)
let strtree:string=safeStringify(fieldTreeRef.value.data)
savePrintTemplate({
name:props.state.formOtherData.formName,
type:"html",
versionid:props.formVersion,
formkey:props.formKey,
formtemplatejson:str,
treedatajson:strtree,
nodecheckedlist:JSON.stringify(fieldTreeRef.value.getCheckedKeys()) //
}).then(resp=>{
if (resp.code!=200){
ElMessage({
message: '模板保存失败'+resp.data.error,
type: 'warning',
})
}else{
ElMessage({
message: "模板已保存",
type: 'success',
})
}
})
}
//
function deepLoop(item:fieldTreeEx){
let data:fieldTree
switch(item.type){
case "grid":
case "tabs":
data={
field:"",
type:item.type,
name: item.unitName,
child:[],
}
break;
default:
data={
field:item.name?? "",
type:item.type,
name:item.item ? item.item.label : ""
}
}
if(item.list){
item.list.forEach(ele => {
if(data.child){
data.child.push(deepLoop(ele))
}else{
data.child=[deepLoop(ele)]
}
});
}
if(item.columns){
item.columns.forEach(ele => {
let column:fieldTree={
field:"",
type:item.type,
name: ele.label
}
if(ele.list){
ele.list.forEach(ele2 => {
if(column.child){
column.child.push(deepLoop(ele2))
}else{
column.child=[deepLoop(ele2)]
}
})
}
data.child?.push(column)
});
}
return data
}
function refreshPrintPage(){
//htmlmode
let section:fieldTree[]=[]
let keys:string[]=[]
htmlRenderData.value=[]
fieldTreeData.value.forEach(item=>{
keys.push(item.field!)
//defaultCheckList.value.push() //
switch(item.type){
case "divider":
case "textarea":
if(section.length>0){
htmlRenderData.value.push(section)
section=[]
}
//if(item.checked!=2) keys.push(item.field!)
htmlRenderData.value.push(item)
break
case "table":
if(section.length>0){
htmlRenderData.value.push(section)
section=[]
}
//if(item.checked==0) keys.push(item.field!)
htmlRenderData.value.push(item)
break
case "grid":
item.child?.forEach(ch=>{
if (ch.child) {
section.push(...ch.child.slice())
}
})
// if(item.checked==0) keys.push(item.field!)
htmlRenderData.value.push(section)
section=[]
break
case "tabs":
if(section.length>0){
htmlRenderData.value.push(section)
section=[]
}
item.child?.forEach(ch=>{
//if(ch.checked==0) keys.push(ch.field!)
htmlRenderData.value.push(ch)
})
break
default:
//if(item.checked!=2) keys.push(item.field!)
section.push(item)
}
})
htmlRenderData.value.push(section)
return keys
}
onMounted(async ()=>{
await getPrintTemplate({
"versionid":props.formVersion,
"formkey":props.formKey
}).then((resp)=>{
printMode.value=resp.data.type
if(resp.data.formtemplatejson!=""){
fieldTreeData.value = JSON.parse(resp.data.treedatajson)
defaultCheckList=JSON.parse(resp.data.nodecheckedlist)
}
}).catch((err)=>{
ElMessage({
message: "模板加载失败,使用默认模板"+err,
type: 'warning',
})
})
if(printMode.value!="custom" &&fieldTreeData.value.length==0){
props.state.formData.list.forEach(item=>{
fieldTreeData.value.push(deepLoop(item))
})
}
treeLoaded.value=true
//printMode
if(printMode.value=="html"){
refreshPrintPage()
}else{
printMode.value="html"
defaultCheckList=refreshPrintPage()
}
})
function updateNodeData(val:fieldTree,val2:boolean,val3:boolean){
if(val2 && val3){
val.checked=0
}else if(val2 || val3){
val.checked=1
}else{
val.checked=2
}
refreshPrintPage()
}
</script>
<template>
<el-tabs class="printpage" v-model="printMode" type="border-card" :tab-position="tabPosition" style="height: 100%">
<el-tab-pane label="默认" name="html">
<div style="display: grid; grid-template-columns: 1fr 4fr;">
<div class="hiprintEpContainer" >
业务字段 <el-button @click="onSaveTreeData">保存模板</el-button>
<el-tree
v-if="treeLoaded"
ref="fieldTreeRef"
node-key="field"
:data="fieldTreeData"
:default-checked-keys="defaultCheckList"
empty-text="组件"
style="max-width: 300px"
:props="{label: 'name',children:'child'}"
show-checkbox
@check-change="updateNodeData"
>
<template #default="{ node, data }">
<span>{{ data.name || '组件' }}</span>
</template>
</el-tree>
</div>
<div style="border: 1px solid black; width: fit-content; margin: 5px;">
<printHtmlRender :name="props.state.formOtherData.formName" :field-tree="htmlRenderData" />
</div>
</div>
</el-tab-pane>
<el-tab-pane label="定制表单" name="custom">
<div style="width: 100%;">
ssss
</div>
</el-tab-pane>
</el-tabs>
</template>
<style lang="scss" scoped>
.hiprintEpContainer,dropTable, .PrintElementOptionSetting{
border: 1px solid black;
margin: 5px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
width: 300px;
}
.defaultContainer{
border: 1px solid black;
margin: 5px;
text-align: center;
display: flex;
flex-direction: column;
overflow-y: scroll;
}
.el-tabs--left .el-tabs__header.is-left {
margin-right: 0;
}
</style>
<style>
.printpage{
.el-tabs__item{
width: 30px;
padding: 0;
height: 160px;
text-wrap: auto;
padding: 7px;
}
}
.el-tabs--right .el-tabs__content,
.el-tabs--left .el-tabs__content {
height: 100%;
}
</style>

251
src/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPageCustom.vue

@ -0,0 +1,251 @@
<!--
@ 作者: han2015
@ 时间: 2025-03-24 15:32:40
@ 备注: 打印模版设计
-->
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import {getPrintTemplate,savePrintTemplate} from '@/api/DesignForm/requestapi'
import {hiprint,defaultElementTypeProvider} from "vue-plugin-hiprint"
import {aProvider,bProvider} from "./vue-plugin-provider.js"
const props = defineProps({
appCont: {
type: Object,
default() {
return {};
},
},
formKey: {
type: String,
default: "",
},
groupKey: {
type: String,
default: "",
},
menuId: {
type: String,
default: "",
},
appPageKey: {
type: String,
default: "",
},
formVersion: {
type: String,
default: "",
},
state: {
type: Object,
default() {
return {};
},
},
});
let hiprintTemplate=ref()
onMounted(()=>{
hiprint.init({
providers:[aProvider(),new defaultElementTypeProvider()],
})
//
hiprint.setConfig()
//
hiprint.setConfig({
movingDistance: 2.5,
text: {
supportOptions: [
{
name: 'styler',
hidden: true
},
{
name: 'formatter',
hidden: true
}
]
}
})
$('.hiprintEpContainer').empty()
hiprint.PrintElementTypeManager.build('.hiprintEpContainer', "aProviderModule"); //aProviderModule--bProviderModule
hiprint.PrintElementTypeManager.buildByHtml($(".ep-draggable-item"))
hiprintTemplate.value= new hiprint.PrintTemplate({
template: {},
settingContainer:"#PrintElementOptionSetting",
})
hiprintTemplate.value.design("#hiprint-printTemplate",{grid:true})
})
// <div style="width: 100%;"></div>
// <div class="businessField" v-for="item in props.state.formData.list">
// <a class="ep-draggable-item" tid="defaultModule.text" style>
// <span class="glyphicon glyphicon-text-width" aria-hidden="true"></span>
// <p class="glyphicon-class">{{item.item.label}}</p>
// </a>
// </div>
</script>
<template>
<div>
<div class="hiprintEpContainer" ></div>
<div class="defaultContainer" >
<div style="width: 100%;">基础组件</div>
<div style="width: 100%;display: grid;grid-template-columns:repeat(3, 1fr)">
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.text" style>
<span class="glyphicon glyphicon-text-width" aria-hidden="true"></span>
<p class="glyphicon-class">文本</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.image" style>
<span class="glyphicon glyphicon-picture" aria-hidden="true"></span>
<p class="glyphicon-class">图片</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.longText">
<span class="glyphicon glyphicon-subscript" aria-hidden="true"></span>
<p class="glyphicon-class">长文</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="aProviderModule.table" style>
<span class="glyphicon glyphicon-th" aria-hidden="true"></span>
<p class="glyphicon-class">表格</p>
</a>
</div>
<div class="drag_item_box" >
<a class="ep-draggable-item" tid="defaultModule.hline" style>
<span class="glyphicon glyphicon-resize-horizontal" aria-hidden="true"></span>
<p class="glyphicon-class">横线</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.vline" style>
<span class="glyphicon glyphicon-resize-vertical" aria-hidden="true"></span>
<p class="glyphicon-class">竖线</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.rect">
<span class="glyphicon glyphicon-unchecked" aria-hidden="true"></span>
<p class="glyphicon-class">矩形</p>
</a>
</div>
<div class="drag_item_box">
<a class="ep-draggable-item" tid="defaultModule.oval">
<span class="glyphicon glyphicon-record" aria-hidden="true"></span>
<p class="glyphicon-class">椭圆</p>
</a>
</div>
</div>
</div>
</div>
<div id="hiprint-printTemplate" class="hiprint-printTemplate" style="margin: 13px;"></div>
<div id="PrintElementOptionSetting" class="PrintElementOptionSetting"></div>
</template>
<style lang="scss" scoped>
.hiprintEpContainer,dropTable, .PrintElementOptionSetting, .defaultContainer{
margin: 5px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
width: 300px;
}
//
.drag_item_box {
border: 1px solid #6f6f70;
border-radius: 5px;
height: 46px;
width: 90px;
margin: 2px;
text-align: center;
align-content: center;
}
.drag_item_box > div {
height: 100%;
width: 100%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.drag_item_box > div > a {
text-align: center;
text-decoration-line: none;
}
.drag_item_box > div > a > span {
font-size: 28px;
}
.drag_item_box > div > a > p {
margin: 0;
}
.drag_item_title {
font-size: 16px;
padding: 12px 6px 0 6px;
font-weight: bold;
}
//
:deep(.hiprint-printElement-image-content) {
img {
content: url("https://docu.hxgk.group/images/2024_07/194a590ff63a017d7a7f55fe6bbb5895.png");
}
}
//
.card-design {
overflow: hidden;
overflow-x: auto;
overflow-y: auto;
}
</style>
<style>
.hiprint-printElement-type ul{
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.businessField, .hiprint-printElement-type a{
display: block;
height: 40px;
width: 138px;
margin: 5px;
border: 1px solid #6f6f70;
border-radius: 5px;
text-align: center;
align-content: center;
}
</style>

424
src/views/sysworkflow/lowcodepage/appPage/appPageForm/vue-plugin-provider.js

@ -0,0 +1,424 @@
/* eslint-disable */
import {hiprint} from 'vue-plugin-hiprint'
// 自定义设计元素1
export const aProvider = function (ops) {
var addElementTypes = function (context) {
context.removePrintElementTypes("aProviderModule");
context.addPrintElementTypes(
"aProviderModule",
[
new hiprint.PrintElementTypeGroup("业务表单", [
{
tid: 'aProviderModule.header', title: '单据表头', data: '单据表头', type: 'text',
options: {
testData: '单据表头',
height: 17,
fontSize: 16.5,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{
tid: 'aProviderModule.type', title: '单据类型', data: '单据类型', type: 'text',
options: {
testData: '单据类型',
height: 16,
fontSize: 15,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{
tid: 'aProviderModule.order', title: '订单编号', data: 'XS888888888', type: 'text',
options: {
field: 'orderId',
testData: 'XS888888888',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'aProviderModule.date', title: '业务日期', data: '2020-01-01', type: 'text',
options: {
field: 'date',
testData: '2020-01-01',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'aProviderModule.barcode', title: '条形码', data: 'XS888888888', type: 'text',
options: {
testData: 'XS888888888',
height: 32,
fontSize: 12,
lineHeight: 18,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle",
textType: "barcode"
}
},
{
tid: 'aProviderModule.qrcode', title: '二维码', data: 'XS888888888', type: 'text',
options: {
testData: 'XS888888888',
height: 32,
fontSize: 12,
lineHeight: 18,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle",
textType: "qrcode"
}
},
{
tid: 'aProviderModule.platform', title: '平台名称', data: '平台名称', type: 'text',
options: {
testData: '平台名称',
height: 17,
fontSize: 16.5,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{tid: 'aProviderModule.logo', title: 'Logo', data: '', type: 'image'},
{
tid: 'aProviderModule.creater', title: '制单人', data: '李四', type: 'text',
options: {
field: 'creater',
testData: '李四',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'aProviderModule.printDate', title: '打印时间', data: '2022-01-01 09:00', type: 'text',
options: {
field: 'printDate',
testData: '2022-01-01 09:00',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'aProviderModule.signer', title: '库管签字', data: '', type: 'text',
options: {
title: '库管签字:',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'aProviderModule.table2', title: '定制表格',
type: 'table',
options: {
field: 'table2',
fields: [
{text: '名称', field: 'NAME'},
{text: '数量', field: 'SL'},
{text: '规格', field: 'GG'},
{text: '条码', field: 'TM'},
{text: '单价', field: 'DJ'},
{text: '金额', field: 'JE'},
{text: '备注', field: 'DETAIL'},
],
},
editable: true,
columnDisplayEditable: true,//列显示是否能编辑
columnDisplayIndexEditable: true,//列顺序显示是否能编辑
columnTitleEditable: true,//列标题是否能编辑
columnResizable: true, //列宽是否能调整
columnAlignEditable: true,//列对齐是否调整
columns: [
[
{title: '名称', align: 'center', field: 'NAME', width: 100},
{title: '数量', align: 'center', field: 'SL', width: 100},
{title: '条码', align: 'center', field: 'TM', width: 100,checked: false},
{title: '规格', align: 'center', field: 'GG', width: 100},
{title: '单价', align: 'center', field: 'DJ', width: 100},
{title: '金额', align: 'center', field: 'JE', width: 100},
{title: '备注', align: 'center', field: 'DETAIL', width: 100},
]
],
footerFormatter: function (options, rows, data, currentPageGridRowsData) {
if (data && data['totalCap']) {
return `<td style="padding:0 10px" colspan="100">${'应收金额大写: ' + data['totalCap']}</td>`
}
return '<td style="padding:0 10px" colspan="100">应收金额大写: </td>'
},
},
{
tid: 'aProviderModule.table', title: '订单数据',
type: 'table',
options: {
//field: 'table',
// tableHeaderRepeat: 'first',
// tableFooterRepeat: 'last',
// fields: [
// {text: '名称'},
// {text: '数量'},
// {text: '规格'},
// {text: '条码'},
// {text: '单价'},
// {text: '金额'},
// ],
},
editable: true,
columnDisplayEditable: true,//列显示是否能编辑
columnDisplayIndexEditable: true,//列顺序显示是否能编辑
columnTitleEditable: true,//列标题是否能编辑
columnResizable: true, //列宽是否能调整
columnAlignEditable: true,//列对齐是否调整
isEnableEditField: true, //编辑字段
isEnableContextMenu: true, //开启右键菜单 默认true
isEnableInsertRow: true, //插入行
isEnableDeleteRow: true, //删除行
isEnableInsertColumn: true, //插入列
isEnableDeleteColumn: true, //删除列
isEnableMergeCell: true, //合并单元格
columns: [
[
{ align: 'center', width: 150},
{ align: 'center', width: 80},
{ align: 'center', width: 80},
{ align: 'center', width: 100},
{ align: 'center', width: 100},
{ align: 'center', width: 100},
],
]
},
{tid: 'aProviderModule.customText', title: '文本', customText: '自定义文本', custom: true, type: 'text'},
{
tid: 'aProviderModule.longText', title: '长文本', type: 'longText', options: {
field: 'test.longText',
width: 200,
testData: '长文本分页/不分页测试'
},
}
])
]
);
};
return {
addElementTypes: addElementTypes
};
};
// 自定义设计元素2
export const bProvider = function (ops) {
var addElementTypes = function (context) {
context.removePrintElementTypes("bProviderModule");
context.addPrintElementTypes(
"bProviderModule",
[
new hiprint.PrintElementTypeGroup("常规", [
{
tid: 'bProviderModule.header', title: '单据表头', data: '单据表头', type: 'text',
options: {
testData: '单据表头',
height: 17,
fontSize: 16.5,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{
tid: 'bProviderModule.type', title: '单据类型', data: '单据类型', type: 'text',
options: {
testData: '单据类型',
height: 16,
fontSize: 15,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{
tid: 'bProviderModule.order', title: '订单编号', data: 'XS888888888', type: 'text',
options: {
field: 'orderId',
testData: 'XS888888888',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'bProviderModule.date', title: '业务日期', data: '2020-01-01', type: 'text',
options: {
field: 'date',
testData: '2020-01-01',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'bProviderModule.barcode', title: '条形码', data: 'XS888888888', type: 'text',
options: {
testData: 'XS888888888',
height: 32,
fontSize: 12,
lineHeight: 18,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle",
textType: "barcode"
}
},
{
tid: 'bProviderModule.qrcode', title: '二维码', data: 'XS888888888', type: 'text',
options: {
testData: 'XS888888888',
height: 32,
fontSize: 12,
lineHeight: 18,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle",
textType: "qrcode"
}
},
{
tid: 'bProviderModule.platform', title: '平台名称', data: '平台名称', type: 'text',
options: {
testData: '平台名称',
height: 17,
fontSize: 16.5,
fontWeight: "700",
textAlign: "center",
hideTitle: true
}
},
{tid: 'bProviderModule.image', title: 'Logo', data: '', type: 'image'},
]),
new hiprint.PrintElementTypeGroup("客户", [
{
tid: 'bProviderModule.khname', title: '客户名称', data: '高级客户', type: 'text',
options: {
field: 'name',
testData: '高级客户',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
{
tid: 'bProviderModule.tel', title: '客户电话', data: '18888888888', type: 'text',
options: {
field: 'tel',
testData: '18888888888',
height: 16,
fontSize: 6.75,
fontWeight: "700",
textAlign: "left",
textContentVerticalAlign: "middle"
}
},
]),
new hiprint.PrintElementTypeGroup("表格/其他", [
{
tid: 'bProviderModule.table', title: '订单数据',
type: 'table',
options: {
field: 'table',
fields: [
{text: '名称', field: 'NAME'},
{text: '数量', field: 'SL'},
{text: '规格', field: 'GG'},
{text: '条码', field: 'TM'},
{text: '单价', field: 'DJ'},
{text: '金额', field: 'JE'},
{text: '备注', field: 'DETAIL'},
],
},
editable: true,
columnDisplayEditable: true,//列显示是否能编辑
columnDisplayIndexEditable: true,//列顺序显示是否能编辑
columnTitleEditable: true,//列标题是否能编辑
columnResizable: true, //列宽是否能调整
columnAlignEditable: true,//列对齐是否调整
columns: [
[
{title: '名称', align: 'center', field: 'NAME', width: 100},
{title: '数量', align: 'center', field: 'SL', width: 100},
{title: '条码', align: 'center', field: 'TM', width: 100},
{title: '规格', align: 'center', field: 'GG', width: 100},
{title: '单价', align: 'center', field: 'DJ', width: 100},
{title: '金额', align: 'center', field: 'JE', width: 100},
{title: '备注', align: 'center', field: 'DETAIL', width: 100},
]
],
footerFormatter: function (options, rows, data, currentPageGridRowsData) {
if (data && data['totalCap']) {
return `<td style="padding:0 10px" colspan="100">${'应收金额大写: ' + data['totalCap']}</td>`
}
return '<td style="padding:0 10px" colspan="100">应收金额大写: </td>'
},
},
{tid: 'bProviderModule.customText', title: '文本', customText: '自定义文本', custom: true, type: 'text'},
{
tid: 'bProviderModule.longText', title: '长文本', type: 'longText', options: {
field: 'test.longText',
width: 200,
testData: '长文本分页/不分页测试'
},
}
]),
new hiprint.PrintElementTypeGroup("辅助", [
{
tid: 'bProviderModule.hline',
title: '横线',
type: 'hline'
},
{
tid: 'bProviderModule.vline',
title: '竖线',
type: 'vline'
},
{
tid: 'bProviderModule.rect',
title: '矩形',
type: 'rect'
},
{
tid: 'bProviderModule.oval',
title: '椭圆',
type: 'oval'
}
])
]
);
};
return {
addElementTypes: addElementTypes
};
};

8
src/views/sysworkflow/lowcodepage/appPage/createAppFormPage.vue

@ -12,7 +12,7 @@ import { getProductionMarkForm } from "@/api/DesignForm/requestapi";
import PageForm from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageForm.vue";
import PageFlow from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageFlow.vue";
import PageList from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageList.vue";
import PrintSetupPage from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage.vue";
import PrintSetupPage2 from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printSetupPage2.vue";
import AiPage from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/aiPage.vue";
import DataBpard from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/dataBoard.vue";
import ContentPresentation from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/contentPresentation.vue";
@ -226,8 +226,8 @@ onBeforeMount(() => {
<el-tab-pane label="② 流程设计" :name="2"> </el-tab-pane>
<el-tab-pane label="③ 列表设计" :name="3"> </el-tab-pane>
<el-tab-pane label="④ 数据看板" :name="4"> </el-tab-pane>
<el-tab-pane label="⑤ 打印设计" :name="5"> </el-tab-pane>
<el-tab-pane label="⑥ 内容呈现设计" :name="6"> </el-tab-pane>
<el-tab-pane label="⑤ 模板设计" :name="5"> </el-tab-pane>
<!-- <el-tab-pane label="⑥ 内容呈现设计" :name="6"> </el-tab-pane> -->
</el-tabs>
</div>
<div class="headRight">
@ -279,7 +279,7 @@ onBeforeMount(() => {
v-model:app-page-key="appPageKey"
v-model:form-version="formVersion"
/>
<PrintSetupPage
<PrintSetupPage2
v-if="tabsActive == 5"
v-model:state="state"
:form-Key="props.formKey"

1
src/views/sysworkflow/lowcodepage/appPage/index.vue

@ -293,7 +293,6 @@ const accessRunApp = () => {
:drawer-with="props.drawerWith"
@openAppPageForm="openAppPageForm"
/>
<CreateAppFormPage
v-if="saveAppFormIsShow"
v-model:is-show="saveAppFormIsShow"

1
src/views/sysworkflow/lowcodepage/appPage/releaseApp/index.vue

@ -73,6 +73,7 @@ const switchChang = () => {
};
</script>
<template>
<div class="appBox">
<el-card class="appCardBox" shadow="always">
<table>

Loading…
Cancel
Save