Kaynağa Gözat

🤓1、打印换成vue-plugin-hiprint 2、升级前后端所有依赖 3、其他优化调整

zuohuaijun 2 yıl önce
ebeveyn
işleme
587b319183

+ 3 - 2
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs

@@ -58,7 +58,8 @@ public static class SqlSugarSetup
         {
             EntityNameService = (type, entity) => // 处理表
             {
-                // 只处理贴了特性 SugarTable 表
+                entity.IsDisabledDelete = true; // 禁止删除非 sqlsugar 创建的列
+                // 只处理贴了特性[SugarTable]表
                 if (!type.GetCustomAttributes<SugarTable>().Any())
                     return;
                 if (config.EnableUnderLine && !entity.DbTableName.Contains('_'))
@@ -66,7 +67,7 @@ public static class SqlSugarSetup
             },
             EntityService = (type, column) => // 处理列
             {
-                // 只处理贴了特性 SugarColumn 
+                // 只处理贴了特性[SugarColumn]
                 if (!type.GetCustomAttributes<SugarColumn>().Any())
                     return;
                 if (new NullabilityInfoContext().Create(type).WriteState is NullabilityState.Nullable)

+ 1 - 1
Admin.NET/Admin.NET.Web.Core/Admin.NET.Web.Core.csproj

@@ -12,7 +12,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.13" />
+    <PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.14" />
     <PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.3" />
   </ItemGroup>
 

+ 1 - 0
Web/index.html

@@ -12,6 +12,7 @@
 			name="description"
 			content="基于 vue3 + CompositionAPI + typescript + vite + element plus,适配手机、平板、pc 的后台开源免费管理系统模板!"
 		/>
+		<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css">
 		<link rel="icon" href="/favicon.ico" />
 		<title>Admin.NET</title>
 	</head>

+ 23 - 24
Web/package.json

@@ -11,23 +11,23 @@
 	},
 	"dependencies": {
 		"@element-plus/icons-vue": "^2.1.0",
-		"@microsoft/signalr": "^7.0.7",
+		"@microsoft/signalr": "^7.0.9",
 		"@wangeditor/editor": "^5.1.23",
 		"@wangeditor/editor-for-vue": "^5.1.12",
 		"animate.css": "^4.1.1",
 		"axios": "^1.4.0",
-		"countup.js": "^2.6.2",
+		"countup.js": "^2.7.0",
 		"cropperjs": "^1.5.13",
-		"echarts": "^5.4.2",
+		"echarts": "^5.4.3",
 		"echarts-gl": "^2.0.9",
 		"echarts-wordcloud": "^2.1.0",
-		"element-plus": "^2.3.7",
+		"element-plus": "^2.3.8",
 		"js-cookie": "^3.0.5",
 		"js-table2excel": "^1.1.2",
 		"jsplumb": "^2.15.6",
 		"lodash-es": "^4.17.21",
-		"mitt": "^3.0.0",
-		"monaco-editor": "^0.39.0",
+		"mitt": "^3.0.1",
+		"monaco-editor": "^0.40.0",
 		"nprogress": "^0.2.0",
 		"pinia": "^2.1.4",
 		"print-js": "^1.6.0",
@@ -43,34 +43,33 @@
 		"vue-grid-layout": "^3.0.0-beta1",
 		"vue-i18n": "^9.2.2",
 		"vue-json-pretty": "^2.2.4",
-		"vue-router": "^4.2.2",
+		"vue-plugin-hiprint": "0.0.54-fix",
+		"vue-router": "^4.2.4",
 		"vue-signature-pad": "^3.0.2",
 		"vue3-tree-org": "^4.2.2",
-		"xlsx-js-style": "^1.2.0",
-		"sv-print": "^0.1.12",
-		"@sv-print/vue3": "^0.1.12",
-		"@sv-print/hiprint": "^0.1.15",
-		"@vitejs/plugin-vue-jsx": "^3.0.1"
+		"xlsx-js-style": "^1.2.0"
 	},
 	"devDependencies": {
-		"@types/lodash-es": "^4.17.7",
-		"@types/node": "^18.15.11",
+		"@types/lodash-es": "^4.17.8",
+		"@types/node": "^20.4.2",
 		"@types/nprogress": "^0.2.0",
 		"@types/sortablejs": "^1.15.1",
-		"@typescript-eslint/eslint-plugin": "^5.58.0",
-		"@typescript-eslint/parser": "^5.58.0",
+		"@typescript-eslint/eslint-plugin": "^6.1.0",
+		"@typescript-eslint/parser": "^6.1.0",
 		"@vitejs/plugin-vue": "^4.1.0",
-		"@vue/compiler-sfc": "^3.2.47",
-		"eslint": "^8.38.0",
-		"eslint-plugin-vue": "^9.10.0",
-		"prettier": "^2.8.7",
-		"sass": "^1.61.0",
-		"typescript": "^5.0.4",
-		"vite": "^4.2.1",
+		"@vitejs/plugin-vue-jsx": "^3.0.1",
+		"@vue/compiler-sfc": "^3.3.4",
+		"eslint": "^8.45.0",
+		"eslint-plugin-vue": "^9.15.1",
+		"less": "^4.1.3",
+		"prettier": "^3.0.0",
+		"sass": "^1.63.6",
+		"typescript": "^5.1.6",
+		"vite": "^4.4.4",
 		"vite-plugin-cdn-import": "^0.3.5",
 		"vite-plugin-compression": "^0.5.1",
 		"vite-plugin-vue-setup-extend-plus": "^0.1.0",
-		"vue-eslint-parser": "^9.1.1"
+		"vue-eslint-parser": "^9.3.1"
 	},
 	"browserslist": [
 		"> 1%",

Dosya farkı çok büyük olduğundan ihmal edildi
+ 387 - 427
Web/pnpm-lock.yaml


+ 36 - 35
Web/public/print-lock.css

@@ -11,16 +11,14 @@
 
 .hiprint-printPaper * {
   box-sizing: border-box;
-  image-rendering: -webkit-optimize-contrast; /* 让图片/标尺稍微清楚一点 */
+  -moz-box-sizing: border-box; /* Firefox */
+  -webkit-box-sizing: border-box; /* Safari */
 }
 
 .hiprint-printPaper *:focus {
   outline: -webkit-focus-ring-color auto 0px;
 }
 
-.hiprint-page-break-avoid {
-  page-break-after: avoid;
-}
 .hiprint-printPaper {
   position: relative;
   padding: 0 0 0 0;
@@ -31,26 +29,30 @@
   overflow-x: hidden;
   overflow: hidden;
 }
-.hiprint-printPaper .hiprint-printPaper-background {
-  position: absolute;
-  pointer-events: none;
-  z-index: 0;
-  left: 0;
-  top: 0;
-}
+
 .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 {
+.hiprint-printPaper, hiprint-printPanel {
   box-sizing: border-box;
   border: 0px;
 }
@@ -75,8 +77,7 @@ hiprint-printPanel {
   border: 1px dashed rgba(170, 170, 170, 0.7);
 }
 
-.design .hiprint-printElement-table-content,
-.design .hiprint-printElement-longText-content {
+.design .hiprint-printElement-table-content, .design .hiprint-printElement-longText-content {
   overflow: hidden;
   box-sizing: border-box;
 }
@@ -92,7 +93,7 @@ hiprint-printPanel {
   padding: 0 0 0 0;
   border: 0.75pt none rgb(0, 0, 0);
   direction: ltr;
-  font-family: "SimSun";
+  font-family: 'SimSun';
   font-size: 9pt;
   font-style: normal;
   font-weight: normal;
@@ -118,7 +119,7 @@ hiprint-printPanel {
   background-repeat: repeat;
   border: 0.75pt none rgb(0, 0, 0);
   direction: ltr;
-  font-family: "SimSun";
+  font-family: 'SimSun';
   font-size: 9pt;
   font-style: normal;
   font-weight: normal;
@@ -135,6 +136,7 @@ hiprint-printPanel {
   /*white-space: pre-wrap*/
 }
 
+
 .hiprint-printElement-table {
   background-color: transparent;
   background-repeat: repeat;
@@ -142,7 +144,7 @@ hiprint-printPanel {
   border-color: rgb(0, 0, 0);
   border-style: none;
   direction: ltr;
-  font-family: "SimSun";
+  font-family: 'SimSun';
   font-size: 9pt;
   font-style: normal;
   font-weight: normal;
@@ -162,12 +164,10 @@ hiprint-printPanel {
   font-weight: 700;
 }
 
-.hiprint-printElement-tableTarget,
-.hiprint-printElement-tableTarget tr,
-.hiprint-printElement-tableTarget td {
+.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);*/
+  /*border-style: none;*/
+  /*border: 1px solid rgb(0, 0, 0);*/
   font-weight: normal;
   direction: ltr;
   padding-bottom: 0pt;
@@ -180,7 +180,7 @@ hiprint-printPanel {
   word-wrap: break-word;
   word-break: break-all;
   /*line-height: 9.75pt;
-    font-size: 9pt;*/
+  font-size: 9pt;*/
 }
 
 .hiprint-printElement-tableTarget-border-all {
@@ -228,8 +228,8 @@ hiprint-printPanel {
 
 .design .hiprint-printElement-table-handle {
   position: absolute;
-  height: 12pt;
-  width: 12pt;
+  height: 21pt;
+  width: 21pt;
   background: red;
   z-index: 1;
 }
@@ -240,10 +240,11 @@ hiprint-printPanel {
   color: gainsboro !important;
 }
 
-.hiprint-printElement-vline,
-.hiprint-printElement-hline {
+.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;
@@ -258,14 +259,14 @@ hiprint-printPanel {
   border-left: 0px none rgb(0, 0, 0) !important;
 }
 
-.hiprint-printElement-oval,
-.hiprint-printElement-rect {
+.hiprint-printElement-oval, .hiprint-printElement-rect {
   border: 0.75pt solid #000;
 }
 
 .hiprint-text-content-middle {
 }
-.hiprint-text-content-middle > div:first-child {
+
+.hiprint-text-content-middle > div {
   display: grid;
   align-items: center;
 }
@@ -273,7 +274,7 @@ hiprint-printPanel {
 .hiprint-text-content-bottom {
 }
 
-.hiprint-text-content-bottom > div:first-child {
+.hiprint-text-content-bottom > div {
   display: grid;
   align-items: flex-end;
 }
@@ -308,10 +309,9 @@ hiprint-printPanel {
   box-sizing: border-box;
 }
 
-.hi-grid-row::after,
-.hi-grid-row::before {
+.hi-grid-row::after, .hi-grid-row::before {
   display: table;
-  content: "";
+  content: '';
   box-sizing: border-box;
 }
 
@@ -332,6 +332,7 @@ hiprint-printPanel {
   padding-left: 0pt;
   padding-right: 0pt;
 }
+
 .hiprint-gridColumnsFooter {
   text-align: left;
   clear: both;

BIN
Web/src/assets/logo.png


+ 3 - 3
Web/src/i18n/index.ts

@@ -14,9 +14,9 @@ import { useThemeConfig } from '/@/stores/themeConfig';
  */
 
 // element plus 自带国际化
-import enLocale from 'element-plus/lib/locale/lang/en';
-import zhcnLocale from 'element-plus/lib/locale/lang/zh-cn';
-import zhtwLocale from 'element-plus/lib/locale/lang/zh-tw';
+import enLocale from 'element-plus/es/locale/lang/en';
+import zhcnLocale from 'element-plus/es/locale/lang/zh-cn';
+import zhtwLocale from 'element-plus/es/locale/lang/zh-tw';
 
 // 定义变量内容
 const messages = {};

+ 1 - 0
Web/src/types/global.d.ts

@@ -7,6 +7,7 @@ declare module '@wangeditor/editor-for-vue';
 declare module 'js-table2excel';
 declare module 'qs';
 declare module 'sortablejs';
+declare module 'vue-plugin-hiprint';
 
 // 声明一个模块,防止引入文件时报错
 declare module '*.json';

+ 31 - 33
Web/src/views/system/print/component/editPrint.vue

@@ -1,8 +1,16 @@
 <template>
 	<div class="sys-print-container">
 		<div class="printDialog">
-			<el-dialog v-model="state.isShowDialog" :show-close="false" :close-on-click-modal="false" fullscreen>
-				<Designer @onDesigned="onDesigned" :autoConnect="false" theme="bumblebee" style="margin: -20px -19px -20px -19px; height: calc(100vh - 45px) !important" />
+			<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" fullscreen>
+				<template #header>
+					<div style="color: #fff">
+						<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
+						<span> {{ props.title }} </span>
+					</div>
+				</template>
+				<div style="margin: -16px 0px 0px 0px">
+					<HiprintDesign ref="hiprintDesignRef" />
+				</div>
 				<template #footer>
 					<span class="dialog-footer" style="margin-top: 10px">
 						<el-button @click="cancel">取 消</el-button>
@@ -48,8 +56,8 @@
 			</el-form>
 			<template #footer>
 				<span class="dialog-footer">
-					<el-button @click="cancel2">取 消</el-button>
-					<el-button type="primary" @click="submit2">确 定</el-button>
+					<el-button @click="templateCancel">取 消</el-button>
+					<el-button type="primary" @click="templateSubmit">确 定</el-button>
 				</span>
 			</template>
 		</el-dialog>
@@ -58,19 +66,18 @@
 
 <script lang="ts" setup name="sysEditPrint">
 import { onMounted, reactive, ref } from 'vue';
-import 'sv-print/dist/style.css';
-import { Designer } from '@sv-print/vue3';
-import { disAutoConnect } from '@sv-print/hiprint';
+import HiprintDesign from '/@/views/system/print/component/hiprint/index.vue';
 
 import { getAPI } from '/@/utils/axios-utils';
 import { SysPrintApi } from '/@/api-services/api';
 import { UpdatePrintInput } from '/@/api-services/models';
 
+const hiprintDesignRef = ref<InstanceType<typeof HiprintDesign>>();
+
 const props = defineProps({
 	title: String,
 });
 const emits = defineEmits(['handleQuery']);
-let svPrint = ref();
 const ruleFormRef = ref();
 const state = reactive({
 	isShowDialog: false,
@@ -78,16 +85,22 @@ const state = reactive({
 	showDialog2: false,
 });
 
-onMounted(async () => {
-	disAutoConnect();
-});
+onMounted(async () => {});
 
 // 打开弹窗
 const openDialog = (row: any) => {
 	state.ruleForm = JSON.parse(JSON.stringify(row));
 	state.isShowDialog = true;
 
-	if (svPrint.value != undefined) loadTemplate();
+	if (hiprintDesignRef.value != undefined) loadTemplate();
+};
+
+// 加载模板
+const loadTemplate = () => {
+	hiprintDesignRef.value?.hiprintTemplate.clear();
+	if (JSON.stringify(state.ruleForm) !== '{}') {
+		hiprintDesignRef.value?.hiprintTemplate.update(JSON.parse(state.ruleForm.template));
+	}
 };
 
 // 取消
@@ -102,36 +115,21 @@ const submit = async () => {
 	if (state.ruleForm.status == undefined) state.ruleForm.status = 1;
 };
 
-// 打印模板页面初始化
-const onDesigned = (e: any) => {
-	svPrint.value = e.detail;
-
-	loadTemplate();
-};
-
-// 加载已有模板
-const loadTemplate = () => {
-	svPrint.value.printTemplate.clear();
-	if (JSON.stringify(state.ruleForm) !== '{}') {
-		svPrint.value.printTemplate.update(JSON.parse(state.ruleForm.template));
-	}
-};
-
-// 取消
-const cancel2 = () => {
+// 模板设置取消
+const templateCancel = () => {
 	state.showDialog2 = false;
 };
 
-// 提交
-const submit2 = async () => {
-	state.ruleForm.template = JSON.stringify(svPrint.value.printTemplate.getJson());
+// 模板设置提交
+const templateSubmit = async () => {
+	state.ruleForm.template = JSON.stringify(hiprintDesignRef.value?.hiprintTemplate.getJson());
 	if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
 		await getAPI(SysPrintApi).apiSysPrintUpdatePost(state.ruleForm);
 	} else {
 		await getAPI(SysPrintApi).apiSysPrintAddPost(state.ruleForm);
 	}
 	cancel();
-	cancel2();
+	templateCancel();
 	emits('handleQuery');
 };
 

+ 358 - 0
Web/src/views/system/print/component/hiprint/index.vue

@@ -0,0 +1,358 @@
+<template>
+	<el-row :gutter="8" style="margin-bottom: 5px">
+		<el-col :span="4">
+			<!-- 流程下拉 模板选择 -->
+			<el-select v-model="state.mode" showSearch @change="changeMode" :defaultValue="0" option-label-prop="label" class="w100">
+				<el-option v-for="(opt, idx) in state.modeList" :key="idx" :label="opt.name" :value="idx">
+					{{ opt.name }}
+				</el-option>
+			</el-select>
+		</el-col>
+
+		<el-col :span="20">
+			<!-- 纸张设置 -->
+			<el-button-group style="margin: 0 2px">
+				<el-button v-for="(value, type) in state.paperTypes" :type="curPaperType === type ? 'primary' : ''" @click="setPaper(type, value)" :key="type">
+					{{ type }}
+				</el-button>
+				<el-popover v-model="state.paperPopVisible" placement="bottom" width="300" title="设置纸张宽高(mm)">
+					<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px">
+						<el-input type="number" v-model="state.paperWidth" style="width: 100px; text-align: center" place="宽(mm)"></el-input>~
+						<el-input type="number" v-model="state.paperHeight" style="width: 100px; text-align: center" place="高(mm)"></el-input>
+					</div>
+					<div>
+						<el-button type="primary" style="width: 100%" @click="otherPaper">确定</el-button>
+					</div>
+					<template #reference>
+						<el-button :type="'other' == curPaperType ? 'primary' : ''" style="margin: 0 10px">自定义宽高</el-button>
+					</template>
+				</el-popover>
+			</el-button-group>
+			<el-input-number style="margin-right: 8px" :value="state.scaleValue" :precision="2" :step="0.1" :min="state.scaleMin" :max="state.scaleMax" @change="changeScale"></el-input-number>
+
+			<el-button-group>
+				<el-tooltip content="左对齐" placement="bottom">
+					<el-button icon="ele-Back" @click="setElsAlign('left')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="居中" placement="bottom">
+					<el-button icon="ele-FullScreen" @click="setElsAlign('vertical')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="右对齐" placement="bottom">
+					<el-button icon="ele-Right" @click="setElsAlign('right')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="顶对齐" placement="bottom">
+					<el-button icon="ele-Top" @click="setElsAlign('top')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="垂直居中" placement="bottom">
+					<el-button icon="ele-DCaret" @click="setElsAlign('horizontal')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="底对齐" placement="bottom">
+					<el-button icon="ele-Bottom" @click="setElsAlign('bottom')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="横向分散" placement="bottom">
+					<el-button icon="ele-Sort" @click="setElsAlign('distributeHor')"> </el-button>
+				</el-tooltip>
+				<el-tooltip content="纵向分散" placement="bottom">
+					<el-button icon="ele-Switch" @click="setElsAlign('distributeVer')"> </el-button>
+				</el-tooltip>
+			</el-button-group>
+
+			<!-- 预览/打印 -->
+			<el-button-group style="margin-left: 8px">
+				<el-button type="primary" icon="ele-RefreshRight" @click="rotatePaper"> 旋转 </el-button>
+				<el-button type="primary" icon="ele-View" @click="preView"> 预览 </el-button>
+				<el-button type="primary" icon="ele-Printer" @click="print"> 直接打印 </el-button>
+				<el-button type="primary" icon="ele-CircleCheck" @click="viewJson"> 模板JSON </el-button>
+				<el-button type="danger" icon="ele-Delete" @click="clearPaper"> 清空模板 </el-button>
+			</el-button-group>
+		</el-col>
+	</el-row>
+
+	<el-row :gutter="8">
+		<el-col :span="4">
+			<el-card style="height: 100%" shadow="never">
+				<el-row>
+					<el-col :span="24" id="hiprintEpContainer" class="rect-printElement-types hiprintEpContainer"> </el-col>
+				</el-row>
+			</el-card>
+		</el-col>
+		<el-col :span="14">
+			<el-card shadow="never" class="card-design">
+				<div id="hiprint-printTemplate" class="hiprint-printTemplate"></div>
+			</el-card>
+		</el-col>
+		<el-col :span="6" class="params_setting_container">
+			<el-card shadow="never">
+				<el-row class="hinnn-layout-sider">
+					<div id="PrintElementOptionSetting"></div>
+				</el-row>
+			</el-card>
+		</el-col>
+	</el-row>
+
+	<el-drawer title="打印模板" v-model="state.templateDialogVisible">
+		<vue-json-pretty :data="state.templateContent" showLength showIcon showLineNumber showSelectController />
+	</el-drawer>
+
+	<!-- 预览 -->
+	<PrintPreview ref="preViewRef" />
+</template>
+
+<script lang="ts" setup name="hiprintDesign">
+import { computed, onMounted, ref, reactive } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import VueJsonPretty from 'vue-json-pretty';
+import 'vue-json-pretty/lib/styles.css';
+
+import { hiprint } from 'vue-plugin-hiprint';
+import providers from './providers';
+import PrintPreview from './preview.vue';
+import printData from './print-data';
+
+let hiprintTemplate = ref();
+
+const preViewRef = ref();
+const state = reactive({
+	// 模板选择
+	mode: 0,
+	modeList: [] as any,
+	// 当前纸张
+	curPaper: {
+		type: 'A4',
+		width: 220,
+		height: 296.6,
+	},
+	// 纸张类型
+	paperTypes: {
+		A3: {
+			width: 420,
+			height: 296.6,
+		},
+		A4: {
+			width: 210,
+			height: 296.6,
+		},
+		A5: {
+			width: 210,
+			height: 147.6,
+		},
+		B3: {
+			width: 500,
+			height: 352.6,
+		},
+		B4: {
+			width: 250,
+			height: 352.6,
+		},
+		B5: {
+			width: 250,
+			height: 175.6,
+		},
+	},
+	scaleValue: 1,
+	scaleMax: 5,
+	scaleMin: 0.5,
+	// 自定义纸张
+	paperPopVisible: false,
+	paperWidth: 220,
+	paperHeight: 80,
+
+	templateDialogVisible: false,
+	templateContent: '',
+});
+
+// 计算当前纸张类型
+const curPaperType = computed(() => {
+	let type = 'other';
+	let types: any = state.paperTypes;
+	for (const key in types) {
+		let item = types[key];
+		let { width, height } = state.curPaper;
+		if (item.width === width && item.height === height) {
+			type = key;
+		}
+	}
+	return type;
+});
+
+// 选择模板
+const changeMode = () => {
+	let provider = providers[state.mode];
+	hiprint.init({
+		providers: [provider.f],
+	});
+
+	// 渲染自定义选项
+	const hiprintEpContainerEl = document.getElementById('hiprintEpContainer');
+	if (hiprintEpContainerEl) {
+		hiprintEpContainerEl.innerHTML = '';
+	}
+	hiprint.PrintElementTypeManager.build('.hiprintEpContainer', provider.value);
+
+	// 渲染绘画模板
+	const hiprintPrintTemplate = document.getElementById('hiprint-printTemplate');
+	if (hiprintPrintTemplate) {
+		hiprintPrintTemplate.innerHTML = '';
+	}
+	// 初始化打印模板设计器
+	let template = {};
+	hiprintTemplate.value = new hiprint.PrintTemplate({
+		template: template,
+		settingContainer: '#PrintElementOptionSetting',
+		paginationContainer: '.hiprint-printPagination',
+	});
+	hiprintTemplate.value.design('#hiprint-printTemplate');
+	// 获取当前放大比例, 当zoom时传true才会有
+	state.scaleValue = hiprintTemplate.value.editingPanel.scale || 1;
+};
+
+/**
+ * 设置纸张大小
+ * @param type [A3, A4, A5, B3, B4, B5, other]
+ * @param value {width,height} mm
+ */
+const setPaper = (type: string, value: { width: number; height: number }) => {
+	try {
+		if (Object.keys(state.paperTypes).includes(type)) {
+			state.curPaper = { type: type, width: value.width, height: value.height };
+			hiprintTemplate.value.setPaper(value.width, value.height);
+		} else {
+			state.curPaper = { type: 'other', width: value.width, height: value.height };
+			hiprintTemplate.value.setPaper(value.width, value.height);
+		}
+	} catch (error) {
+		ElMessage.error(`操作失败: ${error}`);
+	}
+};
+
+// 改变缩放比例
+const changeScale = (currentValue: number, oldValue: number) => {
+	let big = false;
+	currentValue <= oldValue ? (big = false) : (big = true);
+
+	let scaleVal = state.scaleValue;
+	if (big) {
+		scaleVal += 0.1;
+		if (scaleVal > state.scaleMax) scaleVal = 5;
+	} else {
+		scaleVal -= 0.1;
+		if (scaleVal < state.scaleMin) scaleVal = 0.5;
+	}
+	if (hiprintTemplate.value) {
+		// scaleVal: 放大缩小值, false: 不保存(不传也一样), 如果传 true, 打印时也会放大
+		hiprintTemplate.value.zoom(scaleVal);
+		state.scaleValue = scaleVal;
+	}
+};
+
+// 旋转模板
+const rotatePaper = () => {
+	if (hiprintTemplate.value) {
+		hiprintTemplate.value.rotatePaper();
+	}
+};
+
+// 对齐模板
+const setElsAlign = (e: any) => {
+	hiprintTemplate.value.setElsAlign(e);
+};
+
+// 清空模板
+const clearPaper = () => {
+	ElMessageBox.confirm('是否确认清空模板信息?', '警告', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(() => {
+			try {
+				hiprintTemplate.value.clear();
+			} catch (error) {
+				ElMessage.error(`操作失败: ${error}`);
+			}
+		})
+		.catch((err) => {
+			console.log(err);
+		});
+};
+
+// 自定义纸张
+const otherPaper = () => {
+	let value = {
+		width: 0,
+		height: 0,
+	};
+	value.width = state.paperWidth;
+	value.height = state.paperHeight;
+	state.paperPopVisible = false;
+	setPaper('other', value);
+};
+
+// 预览
+const preView = () => {
+	let { width } = state.curPaper;
+	preViewRef.value.showDialog(hiprintTemplate.value, printData, width);
+};
+// 直接打印
+const print = () => {
+	console.log('直接打印');
+};
+
+// 查看模板JSON
+const viewJson = () => {
+	if (hiprintTemplate.value) {
+		var templateJson = JSON.stringify(hiprintTemplate.value.getJson() || {});
+		state.templateContent = JSON.parse(templateJson);
+		state.templateDialogVisible = true;
+	}
+};
+
+onMounted(() => {
+	state.modeList = providers.map((e) => {
+		return { type: e.type, name: e.name, value: e.value };
+	});
+	changeMode();
+	// otherPaper(); // 默认纸张
+});
+
+// 导出对象
+defineExpose({ hiprintTemplate });
+</script>
+
+<style lang="scss" scoped>
+:deep(.rect-printElement-types .hiprint-printElement-type > li > ul > li > a) {
+	// padding: 4px 4px;
+	//color: #1296db;
+	// line-height: 1;
+	height: auto;
+	text-overflow: ellipsis;
+	color: var(--el-color-primary);
+	box-shadow: none !important;
+	border: 1px dashed var(--el-color-primary);
+}
+
+// 默认图片
+:deep(.hiprint-printElement-image-content) {
+	img {
+		content: url('~@/assets/logo.png');
+	}
+}
+
+// 设计容器
+.card-design {
+	overflow: hidden;
+	overflow-x: auto;
+	overflow-y: auto;
+}
+
+:deep(.hiprint-option-item-submitBtn) {
+	background: var(--el-color-primary);
+}
+:deep(.hiprint-option-item-deleteBtn) {
+	background: var(--el-color-danger);
+}
+:deep(.prop-tabs .prop-tab-items li.active) {
+	color: var(--el-color-primary);
+	border-bottom: 2px solid var(--el-color-primary);
+}
+</style>

+ 68 - 0
Web/src/views/system/print/component/hiprint/preview.vue

@@ -0,0 +1,68 @@
+<template>
+	<el-dialog v-model="state.dialogVisible" draggable :close-on-click-modal="false" :width="state.width + 8 + 'mm'">
+		<div id="preview_content" ref="previewContentRef"></div>
+		<template #footer>
+			<el-button :loading="state.waitShowPrinter" type="primary" icon="ele-Printer" @click.stop="print">直接打印</el-button>
+			<el-button type="primary" icon="ele-Printer" @click.stop="toPdf">导出PDF</el-button>
+			<el-button key="close" @click="hideDialog"> 关闭 </el-button>
+		</template>
+	</el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { nextTick, reactive, ref } from 'vue';
+
+const state = reactive({
+	dialogVisible: false,
+	waitShowPrinter: false,
+	width: 0, // 纸张宽 mm
+	printData: {}, // 打印数据
+	hiprintTemplate: {} as any,
+});
+
+const previewContentRef = ref();
+
+const showDialog = (hiprintTemplate: any, printData: {}, width = 210) => {
+	state.dialogVisible = true;
+	state.width = width;
+	state.hiprintTemplate = hiprintTemplate;
+	state.printData = printData;
+	nextTick(() => {
+		const newHtml = hiprintTemplate.getHtml(printData);
+		previewContentRef.value.appendChild(newHtml[0]);
+	});
+};
+
+const print = () => {
+	state.waitShowPrinter = true;
+	state.hiprintTemplate.print(
+		state.printData,
+		{},
+		{
+			callback: () => {
+				state.waitShowPrinter = false;
+			},
+		}
+	);
+};
+
+const toPdf = () => {
+	state.hiprintTemplate.toPdf({}, 'PDF文件');
+};
+
+const hideDialog = () => {
+	state.dialogVisible = false;
+};
+
+defineExpose({ showDialog });
+</script>
+
+<style lang="less" scoped>
+:deep(.ant-modal-body) {
+	padding: 0px;
+}
+
+:deep(.ant-modal-content) {
+	margin-bottom: 24px;
+}
+</style>

+ 40 - 0
Web/src/views/system/print/component/hiprint/print-data.ts

@@ -0,0 +1,40 @@
+// 打印数据
+import logoImg from '/@/assets/logo.png';
+export default {
+	barCode: 'Admin.NET',
+	qrCode: '二维码',
+	longText: '长文本',
+	imageUrl: logoImg,
+	table: [
+		{ NAME: '测试商品01', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品02', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品03', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品04', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品05', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品06', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品07', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品08', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品09', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品10', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品11', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品12', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品13', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品14', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品15', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品16', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品17', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品18', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品19', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品20', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品21', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品22', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品23', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品24', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品25', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品26', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品27', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品28', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品29', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+		{ NAME: '测试商品30', SL: 2, GG: '1*24g', TM: '2O22010100110', DJ: '6.8', JE: '13.6' },
+	],
+};

+ 430 - 0
Web/src/views/system/print/component/hiprint/providers.ts

@@ -0,0 +1,430 @@
+/* eslint-disable */
+import { hiprint } from 'vue-plugin-hiprint';
+import logoImg from '/@/assets/logo.png';
+
+// 自定义设计元素1
+export const aProvider = function () {
+	var addElementTypes = function (context: any) {
+		context.removePrintElementTypes('aProviderModule');
+		context.addPrintElementTypes('aProviderModule', [
+			new hiprint.PrintElementTypeGroup('【公共组件】', [
+				{
+					tid: 'aProviderModule.barcode',
+					title: '条形码',
+					data: '18020030720',
+					type: 'text',
+					options: {
+						field: 'barCode',
+						testData: 'ZUO18020030720',
+						height: 32,
+						fontSize: 12,
+						lineHeight: 18,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+						textType: 'barcode',
+					},
+				},
+				{
+					tid: 'aProviderModule.qrcode',
+					title: '二维码',
+					data: 'ZUO18020030720',
+					type: 'text',
+					options: {
+						field: 'qrCode',
+						testData: 'ZUO18020030720',
+						height: 64,
+						width: 64,
+						fontSize: 12,
+						lineHeight: 18,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+						textType: 'qrcode',
+					},
+				},
+				{
+					tid: 'aProviderModule.table',
+					title: '表格',
+					type: 'table',
+					options: {
+						field: 'table',
+						tableHeaderRepeat: 'first',
+						tableFooterRepeat: 'last',
+						fields: [
+							{ text: '名称', field: 'NAME' },
+							{ text: '数量', field: 'SL' },
+							{ text: '规格', field: 'GG' },
+							{ text: '条码', field: 'TM' },
+							{ text: '单价', field: 'DJ' },
+							{ text: '金额', field: 'JE' },
+						],
+					},
+					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: [
+						[
+							{ title: '名称', align: 'center', field: 'NAME', width: 150 },
+							{ title: '数量', align: 'center', field: 'SL', width: 80 },
+							{ title: '规格', align: 'center', field: 'GG', width: 80, checked: false },
+							{ title: '条码', align: 'center', field: 'TM', width: 100, checked: false },
+							{ title: '单价', align: 'center', field: 'DJ', width: 100 },
+							{ title: '金额', align: 'center', field: 'JE', width: 100, checked: false },
+						],
+					],
+					// footerFormatter: function (options: unknown, rows: unknown, data: any, currentPageGridRowsData: unknown) {
+					//   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.customText',
+					title: '文本',
+					customText: '自定义文本',
+					custom: true,
+					type: 'text',
+					options: {
+						width: 200,
+						testData: '长文本分页/不分页测试',
+					},
+				},
+				{
+					tid: 'aProviderModule.longText',
+					title: '长文本',
+					type: 'longText',
+					options: {
+						field: 'test.longText',
+						width: 200,
+						testData: '长文本分页/不分页测试',
+					},
+				},
+				{ tid: 'aProviderModule.logo', title: 'Logo', data: logoImg, type: 'image', options: { field: 'imageUrl' } },
+				{ tid: 'aProviderModule.hline', title: '横线', type: 'hline' },
+				{ tid: 'aProviderModule.vline', title: '竖线', type: 'vline' },
+				{ tid: 'aProviderModule.rect', title: '矩形', type: 'rect' },
+				{ tid: 'aProviderModule.oval', title: '椭圆', type: 'oval' },
+			]),
+			new hiprint.PrintElementTypeGroup('【视图字段】', [
+				{
+					tid: 'aProviderModule.creater',
+					title: '制表人',
+					data: 'Admin.NET',
+					type: 'text',
+					options: {
+						field: 'creater',
+						testData: 'Admin.NET',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+				{
+					tid: 'aProviderModule.printDate',
+					title: '打印时间',
+					data: '2023-07-20 09:00',
+					type: 'text',
+					options: {
+						field: 'printDate',
+						testData: '2023-07-20 09:00',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+				{
+					tid: 'aProviderModule.signer',
+					title: '库管签字',
+					data: 'Admin.NET',
+					type: 'text',
+					options: {
+						field: 'signer',
+						testData: 'Admin.NET',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+				{
+					tid: 'aProviderModule.director',
+					title: '经理签字',
+					data: 'Admin.NET',
+					type: 'text',
+					options: {
+						field: 'director',
+						testData: 'Admin.NET',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+			]),
+		]);
+	};
+	return {
+		addElementTypes: addElementTypes,
+	};
+};
+
+// 自定义设计元素2
+export const bProvider = function () {
+	var addElementTypes = function (context: any) {
+		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: 'ZUO18020030720',
+					type: 'text',
+					options: {
+						field: 'orderId',
+						testData: 'ZUO18020030720',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+				{
+					tid: 'bProviderModule.date',
+					title: '业务日期',
+					data: '2023-07-20',
+					type: 'text',
+					options: {
+						field: 'date',
+						testData: '2023-07-20',
+						height: 16,
+						fontSize: 6.75,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+					},
+				},
+				{
+					tid: 'bProviderModule.barcode',
+					title: '条形码',
+					data: '18020030720',
+					type: 'text',
+					options: {
+						testData: 'ZUO18020030720',
+						height: 32,
+						fontSize: 12,
+						lineHeight: 18,
+						fontWeight: '700',
+						textAlign: 'left',
+						textContentVerticalAlign: 'middle',
+						textType: 'barcode',
+					},
+				},
+				{
+					tid: 'bProviderModule.qrcode',
+					title: '二维码',
+					data: 'ZUO18020030720',
+					type: 'text',
+					options: {
+						testData: 'ZUO18020030720',
+						height: 64,
+						width: 64,
+						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: logoImg, 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: '18020030720',
+					type: 'text',
+					options: {
+						field: 'tel',
+						testData: '18020030720',
+						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: unknown, rows: unknown, data: any, currentPageGridRowsData: unknown) {
+					//   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,
+	};
+};
+
+// type: 1供货商 2经销商
+export default [
+	{
+		name: 'A设计',
+		value: 'aProviderModule',
+		type: 1,
+		f: aProvider(),
+	},
+	{
+		name: 'B设计',
+		value: 'bProviderModule',
+		type: 2,
+		f: bProvider(),
+	},
+];

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor