af-mobile-client-vue3 1.5.86 → 1.5.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.env.development +1 -0
  2. package/package.json +1 -1
  3. package/src/components/data/UserDetail/index.vue +58 -40
  4. package/src/components/data/UserDetail/recordEntries.ts +20 -1
  5. package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
  6. package/src/components/data/XReportGrid/print.js +184 -184
  7. package/src/router/routes.ts +47 -0
  8. package/src/stores/modules/safecheckStore.ts +47 -0
  9. package/src/utils/PhotoClean.ts +21 -0
  10. package/src/utils/appBackManager.ts +23 -0
  11. package/src/utils/timeUtil.ts +27 -27
  12. package/src/views/SafeInspection/SecurityCertificate/AddDevice/composables/useDeviceForm.ts +129 -0
  13. package/src/views/SafeInspection/SecurityCertificate/AddDevice/index.vue +661 -0
  14. package/src/views/SafeInspection/SecurityCertificate/AddDevice/types/device.ts +59 -0
  15. package/src/views/SafeInspection/SecurityCertificate/OverallHiddenDangers/index.vue +376 -0
  16. package/src/views/SafeInspection/SecurityCertificate/contractSign/index.vue +80 -0
  17. package/src/views/SafeInspection/SecurityCertificate/index.vue +3078 -0
  18. package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/components/PhotoCaptureCard.vue +301 -0
  19. package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/components/PhotoRecognitionInfo.vue +123 -0
  20. package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/components/PhotoStepHeader.vue +187 -0
  21. package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/index.vue +763 -0
  22. package/src/views/SafeInspection/SecurityCertificate/photoSignature/index.vue +248 -0
  23. package/src/views/SafeInspection/SecurityCertificate/slots/GasDevice.vue +132 -0
  24. package/src/views/SafeInspection/SecurityCertificate/userInfo/index.vue +77 -0
  25. package/src/views/SafeInspection/SecurityCertificate/userInfo/upaddress.vue +239 -0
  26. package/src/views/SafeInspection/SecurityFormItem/CameraView/PhotoClean.ts +21 -0
  27. package/src/views/SafeInspection/SecurityFormItem/CameraView/index.vue +560 -0
  28. package/src/views/SafeInspection/SecurityFormItem/FormItem.vue +413 -0
  29. package/src/views/SafeInspection/SecurityFormItem/SignatureComponent/signature.ts +37 -0
  30. package/src/views/SafeInspection/SecurityFormItem/XMultiSelect/index.vue +194 -0
  31. package/src/views/SafeInspection/SecurityFormItem/XSignature/index.vue +68 -0
  32. package/src/views/SafeInspection/SecurityFormItem/index.vue +418 -0
  33. package/src/views/component/SecurityCertificateView/index.vue +242 -0
  34. package/src/views/component/index.vue +4 -0
  35. package/src/views/userRecords/GasPurchaseRecords.vue +19 -0
  36. package/src/views/userRecords/RepairRecords.vue +19 -0
  37. package/src/views/userRecords/TransferGasRecords.vue +19 -0
package/.env.development CHANGED
@@ -1 +1,2 @@
1
1
  NODE_ENV=development
2
+ VITE_RSA_PRIVATE_KEY=MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIRrmftLDHCQqREEJ132Onu+W3vmFbdF7QD751SrcDDGDTfzuz1zBuElvkHhuDBb7KZkXrCIe+MhvX2IvxcLObl3faX+evYlnfj2HRbF0hIpQLuIq22tL06ZcV5w7wqLxUZRpFElIFm8gZTkUvfKXVuHw89e4daDVhU5hK3GHNGTAgMBAAECgYABiINrFaE1E8pkBYx1JJA5yuhL73aUktfd2TeCU00vFg6kyrWCI85Sa2RKu/6CJNZWeOFgdubEUv7a22tRrNIZb3yUMaqtTwSso78mspIOJqjWXTkTH9WPElfTcdpdIse/lgZtPz6egxkuhadSvwrM9Y6NgusiW/5+x95Ct08iOQJBAN5aK+7uISURvGQj2EaRtgGEd8+d4oHl+BYvvTeG3qSgUikHQW3j0sp4gXPw2kxw6sjVgLFOc4FB6LGqwzOTzokCQQCYdYG8ty3Uo/ebUlNzeJFxHXjy/KvBSytAUzAXkRu3nZrkEaPQsi3dgOkZgk+F1fMDzfQ4EbDIU6xvqOoZXHg7AkATCW9XfoXR8anKfRMoP5Nwn9HOMbtR2cmaxK2TknV/bMZ8AsYETYwfj5+tuIJIJybC2RyykX/sIiN1CqS5xr7ZAkArj19rMRdaKyMi8MnBM1Cy9g3Jt2HHj5ejAGG8SgyWUOShh1y70z0BjcSMMkxQXAncK2s83ekZw7aADM4eQupjAkARRgTwwMOnn3IoKmQusKhZk0uxilZ4Zc2LH6Z4GiWnvteM0W8Zw4Z1lJUcjgQq3dGqL2RdmzeQZ+HgPIOXrZVK
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.5.86",
4
+ "version": "1.5.88",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -2,13 +2,14 @@
2
2
  import type { RecordEntry } from './recordEntries'
3
3
  import type { BaseUser, ConfigItem } from './types'
4
4
  import useLoading from '@af-mobile-client-vue3/hooks/useLoading'
5
+ import { getConfigByNameAsync } from '@af-mobile-client-vue3/services/api/common'
5
6
  import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
6
7
  import { Button as VanButton, Empty as VanEmpty, Loading as VanLoading } from 'vant'
7
- import { computed, onActivated, ref, watch } from 'vue'
8
+ import { computed, onActivated, onMounted, ref, watch } from 'vue'
8
9
  import { useRouter } from 'vue-router'
9
10
  import InfoDisplay from '../InfoDisplay/index.vue'
10
11
  import { getCacheUserDetail, getRecentBusinessTime } from './api'
11
- import { defaultRecordEntries } from './recordEntries'
12
+ // import { defaultRecordEntries } from './recordEntries'
12
13
 
13
14
  interface Props {
14
15
  userInfoId: string // 用户ID(必传)
@@ -37,7 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
37
38
  showBottomButtons: false,
38
39
  showHeader: false,
39
40
  headerTitle: '用户档案详情',
40
- recordEntries: () => defaultRecordEntries,
41
+ recordEntries: () => [],
41
42
  })
42
43
 
43
44
  const emit = defineEmits<Emits>()
@@ -47,6 +48,41 @@ const router = useRouter()
47
48
  const user = ref<BaseUser | null>(null)
48
49
  const { loading: userLoading, startLoading: startUserLoading, endLoading: endUserLoading } = useLoading(false)
49
50
  const userError = ref<string | null>(null)
51
+ const allRecords = ref<RecordEntry[]>([])
52
+ const fixedUserDetails = ref<ConfigItem[]>([
53
+ { label: '联系电话', field: 'f_user_phone' },
54
+ { label: '用户类型', field: 'f_user_type' },
55
+ { label: '用户地址', field: 'f_address', full: true },
56
+ { label: '表具类型', field: 'f_meter_type' },
57
+ { label: '表具编号', field: 'f_meternumber' },
58
+ {
59
+ label: '卡号',
60
+ field: 'f_card_id',
61
+ condition: data => data.f_meter_type?.includes('卡表') || data.f_hascard === '是',
62
+ },
63
+ {
64
+ label: '账户余额',
65
+ field: 'f_balance',
66
+ format: value => `¥ ${value}`,
67
+ condition: data => !data.f_meter_type?.includes('物联网表') || (data.f_meter_type?.includes('物联网表') && data.f_user_balance > 0),
68
+ },
69
+ {
70
+ label: '表上余额',
71
+ field: 'f_balance_amount',
72
+ condition: data => data.f_meter_type?.includes('物联网表'),
73
+ },
74
+ { label: '购气次数', field: 'f_times' },
75
+ {
76
+ label: '累计购气(m³)',
77
+ field: 'f_total_gas',
78
+ format: value => `${value}m³`,
79
+ },
80
+ {
81
+ label: '阀控状态',
82
+ field: 'f_valve_state',
83
+ condition: data => data.f_meter_type?.includes('物联网表'),
84
+ },
85
+ ])
50
86
 
51
87
  // 控制用户信息展开收起
52
88
  const showUserInfo = ref(false)
@@ -77,40 +113,7 @@ const userDetailConfig = computed<ConfigItem[]>(() => {
77
113
  if (!user.value)
78
114
  return []
79
115
 
80
- return [
81
- { label: '联系电话', field: 'f_user_phone' },
82
- { label: '用户类型', field: 'f_user_type' },
83
- { label: '用户地址', field: 'f_address', full: true },
84
- { label: '表具类型', field: 'f_meter_type' },
85
- { label: '表具编号', field: 'f_meternumber' },
86
- {
87
- label: '卡号',
88
- field: 'f_card_id',
89
- condition: data => data.f_meter_type?.includes('卡表') || data.f_hascard === '是',
90
- },
91
- {
92
- label: '账户余额',
93
- field: 'f_balance',
94
- format: value => `¥ ${value}`,
95
- condition: data => !data.f_meter_type?.includes('物联网表') || (data.f_meter_type?.includes('物联网表') && data.f_user_balance > 0),
96
- },
97
- {
98
- label: '表上余额',
99
- field: 'f_balance_amount',
100
- condition: data => data.f_meter_type?.includes('物联网表'),
101
- },
102
- { label: '购气次数', field: 'f_times' },
103
- {
104
- label: '累计购气(m³)',
105
- field: 'f_total_gas',
106
- format: value => `${value}m³`,
107
- },
108
- {
109
- label: '阀控状态',
110
- field: 'f_valve_state',
111
- condition: data => data.f_meter_type?.includes('物联网表'),
112
- },
113
- ].filter(item => !item.condition || item.condition(user.value))
116
+ return fixedUserDetails.value.filter(item => !item?.condition || item?.condition(user.value))
114
117
  })
115
118
 
116
119
  // 筛选符合当前用户表具类型的记录入口
@@ -118,9 +121,13 @@ const filteredRecordEntries = computed(() => {
118
121
  if (!user.value?.f_meter_type)
119
122
  return []
120
123
 
121
- return props.recordEntries.filter(entry =>
122
- entry.forMeterTypes.includes(user.value!.f_meter_type),
123
- )
124
+ return props?.recordEntries || props?.recordEntries?.length === 0
125
+ ? allRecords.value.filter(entry =>
126
+ entry.forMeterTypes.includes(user.value!.f_meter_type),
127
+ )
128
+ : props.recordEntries.filter(entry =>
129
+ entry.forMeterTypes.includes(user.value!.f_meter_type),
130
+ )
124
131
  })
125
132
 
126
133
  // 获取用户详情
@@ -243,6 +250,17 @@ watch(() => props.userInfoId, async (newId) => {
243
250
  }
244
251
  }
245
252
  }, { immediate: true })
253
+
254
+ onMounted(async () => {
255
+ const config: any = await getConfigByNameAsync('userInfoAndListConfig', 'af-revenue')
256
+ if (config) {
257
+ fixedUserDetails.value = config.info.map((item1: { field: string }) => {
258
+ const found = fixedUserDetails.value.find(item2 => item1.field === item2.field)
259
+ return found || item1
260
+ })
261
+ allRecords.value = config.records || []
262
+ }
263
+ })
246
264
  </script>
247
265
 
248
266
  <template>
@@ -1,4 +1,8 @@
1
1
  // 记录入口默认配置
2
+ // 此处如果导入getConfigByNameAsync,则项目无法启动且无法提交
3
+ // import { getConfigByNameAsync } from '@af-mobile-client-vue3/services/api/common'
4
+ // import { ref } from 'vue'
5
+
2
6
  export interface RecordEntry {
3
7
  id: string
4
8
  title: string
@@ -11,7 +15,7 @@ export interface RecordEntry {
11
15
  forMeterTypes: string[]
12
16
  }
13
17
 
14
- // 默认记录入口配置
18
+ // 默认记录入口配置(静态默认值,用于插件初始化等场景)
15
19
  export const defaultRecordEntries: RecordEntry[] = [
16
20
  {
17
21
  id: 'OperateRecords',
@@ -157,3 +161,18 @@ export const defaultRecordEntries: RecordEntry[] = [
157
161
  forMeterTypes: ['气量卡表', '金额卡表', '物联网表', '机表'],
158
162
  },
159
163
  ]
164
+
165
+ // 响应式记录入口配置,可被 API 数据更新
166
+ // export const recordEntries = ref<RecordEntry[]>([...defaultRecordEntries])
167
+
168
+ /**
169
+ * 从 API 获取记录入口配置并更新 recordEntries
170
+ * @returns API 返回的配置数据
171
+ */
172
+ // export async function initRecordEntries() {
173
+ // const data = await getConfigByNameAsync('userInfoAndListConfig', 'af-revenue')
174
+ // if (data) {
175
+ // recordEntries.value = data?.records as RecordEntry[]
176
+ // }
177
+ // return data
178
+ // }
@@ -1,33 +1,33 @@
1
- <script setup lang="ts">
2
- import { onMounted, ref } from 'vue'
3
- import XReport from './XReport.vue'
4
-
5
- const mainRef = ref()
6
-
7
- onMounted(() => {
8
- // 初始化逻辑
9
- })
10
- </script>
11
-
12
- <template>
13
- <div id="test">
14
- <van-card :bordered="false">
15
- <XReport
16
- ref="mainRef"
17
- :use-oss-for-img="false"
18
- config-name="nurseWorkstationCover"
19
- server-name="af-his"
20
- :show-img-in-cell="true"
21
- :display-only="true"
22
- :edit-mode="false"
23
- :show-save-button="false"
24
- :no-padding="true"
25
- :dont-format="true"
26
- />
27
- </van-card>
28
- </div>
29
- </template>
30
-
31
- <style scoped>
32
-
33
- </style>
1
+ <script setup lang="ts">
2
+ import { onMounted, ref } from 'vue'
3
+ import XReport from './XReport.vue'
4
+
5
+ const mainRef = ref()
6
+
7
+ onMounted(() => {
8
+ // 初始化逻辑
9
+ })
10
+ </script>
11
+
12
+ <template>
13
+ <div id="test">
14
+ <van-card :bordered="false">
15
+ <XReport
16
+ ref="mainRef"
17
+ :use-oss-for-img="false"
18
+ config-name="nurseWorkstationCover"
19
+ server-name="af-his"
20
+ :show-img-in-cell="true"
21
+ :display-only="true"
22
+ :edit-mode="false"
23
+ :show-save-button="false"
24
+ :no-padding="true"
25
+ :dont-format="true"
26
+ />
27
+ </van-card>
28
+ </div>
29
+ </template>
30
+
31
+ <style scoped>
32
+
33
+ </style>
@@ -1,184 +1,184 @@
1
- // print.js
2
-
3
- export function printElement(elementToPrint) {
4
- // 创建一个新的浏览器窗口
5
- const printWindow = window.open('', '_blank', 'height=1024,width=768')
6
- // 设置新窗口的文档内容
7
- printWindow.document.write(`
8
- <html>
9
- <head>
10
- <title>Print</title>
11
- <style>
12
- @page {
13
- size: auto;
14
- margin: 0mm;
15
- }
16
- html, body {
17
- margin: 0;
18
- padding: 0;
19
- width: 100%;
20
- height: 100%;
21
- }
22
- #print-container {
23
- display: none
24
- }
25
- .img{
26
- width: 95%;
27
- height: 180px;
28
- object-fit: cover;
29
- }
30
- .reportMain {
31
- text-align: center;
32
- margin: 0 auto;
33
- font-size: 16px;
34
- color: #000;
35
- background-color: #fff;
36
- border-radius: 8px;
37
-
38
- .reportTitle {
39
- font-weight: bold;
40
- }
41
-
42
- .subTitle {
43
- display: flex;
44
- justify-content: space-between;
45
- margin-bottom: 1%;
46
-
47
- .subTitleItems {
48
- max-width: 30%;
49
- }
50
- }
51
-
52
- .inputsDiv {
53
- display: flex;
54
- justify-content: space-between;
55
- .inputsDivItem {
56
- display: flex;
57
- align-items: center;
58
- padding: 0 4px;
59
- white-space: nowrap;
60
- .inputsDivItemLabel {
61
- padding: 0 4px;
62
- }
63
- }
64
- }
65
-
66
- .reportTable {
67
- width: 100%;
68
- border-collapse: collapse;
69
- table-layout:fixed;
70
- word-break:break-all;
71
- text-align: center;
72
- }
73
- }
74
- .reportMainForDisplay {
75
- text-align: center;
76
- margin: 10% auto;
77
- font-size: 16px;
78
- color: #000;
79
- background-color: #fff;
80
- border-radius: 8px;
81
-
82
- .reportTitle {
83
- font-weight: bold;
84
- }
85
-
86
- .subTitle {
87
- display: flex;
88
- justify-content: space-between;
89
-
90
- .subTitleItems {
91
- max-width: 30%;
92
- }
93
- }
94
-
95
- .inputsDiv {
96
- display: flex;
97
- justify-content: space-around;
98
- .inputsDivItem {
99
- display: flex;
100
- align-items: center;
101
- padding: 0 4px;
102
- white-space: nowrap;
103
- .inputsDivItemLabel {
104
- padding: 0 4px;
105
- }
106
- }
107
- }
108
-
109
- .reportTable {
110
- width: 100%;
111
- border-collapse: collapse;
112
- table-layout:fixed;
113
- word-break:break-all;
114
- }
115
- }
116
- .reportMainNoPadding {
117
- text-align: center;
118
- margin: 0 auto;
119
- font-size: 16px;
120
- color: #000;
121
- background-color: #fff;
122
- border-radius: 8px;
123
-
124
- .reportTitle {
125
- font-weight: bold;
126
- }
127
-
128
- .subTitle {
129
- display: flex;
130
- justify-content: space-between;
131
-
132
- .subTitleItems {
133
- max-width: 30%;
134
- }
135
- }
136
-
137
- .inputsDiv {
138
- display: flex;
139
- justify-content: space-between;
140
- .inputsDivItem {
141
- display: flex;
142
- align-items: center;
143
- padding: 0 4px;
144
- white-space: nowrap;
145
- .inputsDivItemLabel {
146
- padding: 0 4px;
147
- }
148
- }
149
- }
150
-
151
- .reportTable {
152
- width: 100%;
153
- border-collapse: collapse;
154
- table-layout:fixed;
155
- word-break:break-all;
156
- }
157
- }
158
- .tools{
159
- position: fixed;
160
- right: 2%;
161
- text-align: right;
162
- width: 60%;
163
- cursor: pointer;
164
- .toolsItem{
165
- width: 15%;
166
- margin-right: 3%;
167
- display: inline-block;
168
- }
169
- }
170
- </style>
171
- </head>
172
- <body>
173
- <!-- 将需要打印的元素内容复制到新窗口中 -->
174
- ${elementToPrint.innerHTML}
175
- </body>
176
- </html>
177
- `)
178
- // 延迟执行打印,以确保新窗口的内容已加载完成
179
- printWindow.document.close() // 关闭文档流,确保内容完全加载
180
- setTimeout(() => {
181
- printWindow.print() // 调用打印方法
182
- printWindow.close()
183
- }, 500) // 延迟500毫秒后执行打印
184
- }
1
+ // print.js
2
+
3
+ export function printElement(elementToPrint) {
4
+ // 创建一个新的浏览器窗口
5
+ const printWindow = window.open('', '_blank', 'height=1024,width=768')
6
+ // 设置新窗口的文档内容
7
+ printWindow.document.write(`
8
+ <html>
9
+ <head>
10
+ <title>Print</title>
11
+ <style>
12
+ @page {
13
+ size: auto;
14
+ margin: 0mm;
15
+ }
16
+ html, body {
17
+ margin: 0;
18
+ padding: 0;
19
+ width: 100%;
20
+ height: 100%;
21
+ }
22
+ #print-container {
23
+ display: none
24
+ }
25
+ .img{
26
+ width: 95%;
27
+ height: 180px;
28
+ object-fit: cover;
29
+ }
30
+ .reportMain {
31
+ text-align: center;
32
+ margin: 0 auto;
33
+ font-size: 16px;
34
+ color: #000;
35
+ background-color: #fff;
36
+ border-radius: 8px;
37
+
38
+ .reportTitle {
39
+ font-weight: bold;
40
+ }
41
+
42
+ .subTitle {
43
+ display: flex;
44
+ justify-content: space-between;
45
+ margin-bottom: 1%;
46
+
47
+ .subTitleItems {
48
+ max-width: 30%;
49
+ }
50
+ }
51
+
52
+ .inputsDiv {
53
+ display: flex;
54
+ justify-content: space-between;
55
+ .inputsDivItem {
56
+ display: flex;
57
+ align-items: center;
58
+ padding: 0 4px;
59
+ white-space: nowrap;
60
+ .inputsDivItemLabel {
61
+ padding: 0 4px;
62
+ }
63
+ }
64
+ }
65
+
66
+ .reportTable {
67
+ width: 100%;
68
+ border-collapse: collapse;
69
+ table-layout:fixed;
70
+ word-break:break-all;
71
+ text-align: center;
72
+ }
73
+ }
74
+ .reportMainForDisplay {
75
+ text-align: center;
76
+ margin: 10% auto;
77
+ font-size: 16px;
78
+ color: #000;
79
+ background-color: #fff;
80
+ border-radius: 8px;
81
+
82
+ .reportTitle {
83
+ font-weight: bold;
84
+ }
85
+
86
+ .subTitle {
87
+ display: flex;
88
+ justify-content: space-between;
89
+
90
+ .subTitleItems {
91
+ max-width: 30%;
92
+ }
93
+ }
94
+
95
+ .inputsDiv {
96
+ display: flex;
97
+ justify-content: space-around;
98
+ .inputsDivItem {
99
+ display: flex;
100
+ align-items: center;
101
+ padding: 0 4px;
102
+ white-space: nowrap;
103
+ .inputsDivItemLabel {
104
+ padding: 0 4px;
105
+ }
106
+ }
107
+ }
108
+
109
+ .reportTable {
110
+ width: 100%;
111
+ border-collapse: collapse;
112
+ table-layout:fixed;
113
+ word-break:break-all;
114
+ }
115
+ }
116
+ .reportMainNoPadding {
117
+ text-align: center;
118
+ margin: 0 auto;
119
+ font-size: 16px;
120
+ color: #000;
121
+ background-color: #fff;
122
+ border-radius: 8px;
123
+
124
+ .reportTitle {
125
+ font-weight: bold;
126
+ }
127
+
128
+ .subTitle {
129
+ display: flex;
130
+ justify-content: space-between;
131
+
132
+ .subTitleItems {
133
+ max-width: 30%;
134
+ }
135
+ }
136
+
137
+ .inputsDiv {
138
+ display: flex;
139
+ justify-content: space-between;
140
+ .inputsDivItem {
141
+ display: flex;
142
+ align-items: center;
143
+ padding: 0 4px;
144
+ white-space: nowrap;
145
+ .inputsDivItemLabel {
146
+ padding: 0 4px;
147
+ }
148
+ }
149
+ }
150
+
151
+ .reportTable {
152
+ width: 100%;
153
+ border-collapse: collapse;
154
+ table-layout:fixed;
155
+ word-break:break-all;
156
+ }
157
+ }
158
+ .tools{
159
+ position: fixed;
160
+ right: 2%;
161
+ text-align: right;
162
+ width: 60%;
163
+ cursor: pointer;
164
+ .toolsItem{
165
+ width: 15%;
166
+ margin-right: 3%;
167
+ display: inline-block;
168
+ }
169
+ }
170
+ </style>
171
+ </head>
172
+ <body>
173
+ <!-- 将需要打印的元素内容复制到新窗口中 -->
174
+ ${elementToPrint.innerHTML}
175
+ </body>
176
+ </html>
177
+ `)
178
+ // 延迟执行打印,以确保新窗口的内容已加载完成
179
+ printWindow.document.close() // 关闭文档流,确保内容完全加载
180
+ setTimeout(() => {
181
+ printWindow.print() // 调用打印方法
182
+ printWindow.close()
183
+ }, 500) // 延迟500毫秒后执行打印
184
+ }