af-mobile-client-vue3 1.6.52 → 1.6.54

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.6.52",
4
+ "version": "1.6.54",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -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
+ }
@@ -1,47 +1,47 @@
1
- import { defineStore } from 'pinia'
2
- import { ref } from 'vue'
3
-
4
- const useSafecheckStore = defineStore('safecheck', () => {
5
- // 换表id
6
- const changeTableId = ref(null)
7
- const tenantName = ref(null)
8
-
9
- // 设置换表id
10
- function setChangeTableId(id) {
11
- changeTableId.value = id
12
- }
13
-
14
- // 设置租户名称
15
- function setTenantName(name) {
16
- tenantName.value = name
17
- }
18
-
19
- // 获取换表id
20
- function getChangeTableId() {
21
- return changeTableId.value
22
- }
23
-
24
- // 获取租户名称
25
- function getTenantName() {
26
- return tenantName.value
27
- }
28
-
29
- // 清空换表id
30
- function clearChangeTableId() {
31
- changeTableId.value = null
32
- }
33
-
34
- return {
35
- changeTableId,
36
- tenantName,
37
- setTenantName,
38
- getTenantName,
39
- setChangeTableId,
40
- getChangeTableId,
41
- clearChangeTableId,
42
- }
43
- }, {
44
- persist: true, // 如果需要持久化
45
- })
46
-
47
- export default useSafecheckStore
1
+ import { defineStore } from 'pinia'
2
+ import { ref } from 'vue'
3
+
4
+ const useSafecheckStore = defineStore('safecheck', () => {
5
+ // 换表id
6
+ const changeTableId = ref(null)
7
+ const tenantName = ref(null)
8
+
9
+ // 设置换表id
10
+ function setChangeTableId(id) {
11
+ changeTableId.value = id
12
+ }
13
+
14
+ // 设置租户名称
15
+ function setTenantName(name) {
16
+ tenantName.value = name
17
+ }
18
+
19
+ // 获取换表id
20
+ function getChangeTableId() {
21
+ return changeTableId.value
22
+ }
23
+
24
+ // 获取租户名称
25
+ function getTenantName() {
26
+ return tenantName.value
27
+ }
28
+
29
+ // 清空换表id
30
+ function clearChangeTableId() {
31
+ changeTableId.value = null
32
+ }
33
+
34
+ return {
35
+ changeTableId,
36
+ tenantName,
37
+ setTenantName,
38
+ getTenantName,
39
+ setChangeTableId,
40
+ getChangeTableId,
41
+ clearChangeTableId,
42
+ }
43
+ }, {
44
+ persist: true, // 如果需要持久化
45
+ })
46
+
47
+ export default useSafecheckStore
@@ -1,88 +1,88 @@
1
- import { defineStore } from 'pinia'
2
- import { ref } from 'vue'
3
-
4
- export interface StepToolsInfo {
5
- workflowId: string
6
- stepDefines: any
7
- formData: any
8
- currentStepData: any
9
- readOnly: boolean
10
- callbackFunction: Function
11
- businessData: any
12
- }
13
-
14
- export const useStepStore = defineStore('apply-step', () => {
15
- const stepState = ref<StepToolsInfo>({
16
- workflowId: '0',
17
- stepDefines: undefined,
18
- formData: undefined,
19
- currentStepData: undefined,
20
- readOnly: false,
21
- callbackFunction: () => {
22
- return true
23
- },
24
- businessData: undefined,
25
- })
26
- const getWorkflowId = () => {
27
- return stepState.value.workflowId || '0'
28
- }
29
- const getStepDefines = () => {
30
- return stepState.value.stepDefines || {}
31
- }
32
- const getFormData = () => {
33
- return stepState.value.formData || {}
34
- }
35
- const getReadOnly = () => {
36
- return stepState.value.readOnly || false
37
- }
38
- const getCurrentStepData = () => {
39
- return stepState.value.currentStepData || {}
40
- }
41
- const getCallbackFunction = () => {
42
- return stepState.value.callbackFunction || undefined
43
- }
44
- const getBusinessData = () => {
45
- return stepState.value.businessData || {}
46
- }
47
- const setWorkflowId = (workflowId: string) => {
48
- stepState.value.workflowId = workflowId
49
- }
50
- const setStepDefines = (stepDefines: any) => {
51
- stepState.value.stepDefines = stepDefines
52
- }
53
- const setFormData = (formData: any) => {
54
- stepState.value.formData = formData
55
- }
56
- const setCurrentStepData = (currentStepData: any) => {
57
- stepState.value.currentStepData = currentStepData
58
- }
59
- const setReadOnly = (readOnly: boolean) => {
60
- stepState.value.readOnly = readOnly
61
- }
62
- const setCallbackFunction = (callbackFunction: Function) => {
63
- stepState.value.callbackFunction = callbackFunction
64
- }
65
- const setBusinessData = (businessData: any) => {
66
- stepState.value.businessData = businessData
67
- }
68
-
69
- return {
70
- stepState,
71
- getWorkflowId,
72
- getStepDefines,
73
- getFormData,
74
- getCurrentStepData,
75
- getReadOnly,
76
- getCallbackFunction,
77
- getBusinessData,
78
- setWorkflowId,
79
- setStepDefines,
80
- setFormData,
81
- setCurrentStepData,
82
- setReadOnly,
83
- setCallbackFunction,
84
- setBusinessData,
85
- }
86
- })
87
-
88
- export default useStepStore
1
+ import { defineStore } from 'pinia'
2
+ import { ref } from 'vue'
3
+
4
+ export interface StepToolsInfo {
5
+ workflowId: string
6
+ stepDefines: any
7
+ formData: any
8
+ currentStepData: any
9
+ readOnly: boolean
10
+ callbackFunction: Function
11
+ businessData: any
12
+ }
13
+
14
+ export const useStepStore = defineStore('apply-step', () => {
15
+ const stepState = ref<StepToolsInfo>({
16
+ workflowId: '0',
17
+ stepDefines: undefined,
18
+ formData: undefined,
19
+ currentStepData: undefined,
20
+ readOnly: false,
21
+ callbackFunction: () => {
22
+ return true
23
+ },
24
+ businessData: undefined,
25
+ })
26
+ const getWorkflowId = () => {
27
+ return stepState.value.workflowId || '0'
28
+ }
29
+ const getStepDefines = () => {
30
+ return stepState.value.stepDefines || {}
31
+ }
32
+ const getFormData = () => {
33
+ return stepState.value.formData || {}
34
+ }
35
+ const getReadOnly = () => {
36
+ return stepState.value.readOnly || false
37
+ }
38
+ const getCurrentStepData = () => {
39
+ return stepState.value.currentStepData || {}
40
+ }
41
+ const getCallbackFunction = () => {
42
+ return stepState.value.callbackFunction || undefined
43
+ }
44
+ const getBusinessData = () => {
45
+ return stepState.value.businessData || {}
46
+ }
47
+ const setWorkflowId = (workflowId: string) => {
48
+ stepState.value.workflowId = workflowId
49
+ }
50
+ const setStepDefines = (stepDefines: any) => {
51
+ stepState.value.stepDefines = stepDefines
52
+ }
53
+ const setFormData = (formData: any) => {
54
+ stepState.value.formData = formData
55
+ }
56
+ const setCurrentStepData = (currentStepData: any) => {
57
+ stepState.value.currentStepData = currentStepData
58
+ }
59
+ const setReadOnly = (readOnly: boolean) => {
60
+ stepState.value.readOnly = readOnly
61
+ }
62
+ const setCallbackFunction = (callbackFunction: Function) => {
63
+ stepState.value.callbackFunction = callbackFunction
64
+ }
65
+ const setBusinessData = (businessData: any) => {
66
+ stepState.value.businessData = businessData
67
+ }
68
+
69
+ return {
70
+ stepState,
71
+ getWorkflowId,
72
+ getStepDefines,
73
+ getFormData,
74
+ getCurrentStepData,
75
+ getReadOnly,
76
+ getCallbackFunction,
77
+ getBusinessData,
78
+ setWorkflowId,
79
+ setStepDefines,
80
+ setFormData,
81
+ setCurrentStepData,
82
+ setReadOnly,
83
+ setCallbackFunction,
84
+ setBusinessData,
85
+ }
86
+ })
87
+
88
+ export default useStepStore
@@ -1,21 +1,21 @@
1
- // 提取对象中的图片/文件ID数组(兼容多种字段名)
2
- export function getPhotosFromAny(obj: any, type: string): string[] {
3
- const candidates = [obj[type]]
4
-
5
- for (const c of candidates) {
6
- if (Array.isArray(c) && c.length > 0) {
7
- // 检查是否为对象数组,如果是则提取photo_name字段
8
- if (typeof c[0] === 'object' && c[0] !== null) {
9
- const ids = c.map((item: any) => {
10
- const id = item?.photo_name || item?.id || item?.uid || item?.fileId || item?.value
11
- || item?.response?.id || item?.response?.fileId || item?.resourceId
12
- return id != null && id !== '' ? String(id) : null
13
- }).filter((id: string | null) => id !== null)
14
- return ids as string[]
15
- }
16
- // 如果是字符串数组,直接返回
17
- return c as string[]
18
- }
19
- }
20
- return []
21
- }
1
+ // 提取对象中的图片/文件ID数组(兼容多种字段名)
2
+ export function getPhotosFromAny(obj: any, type: string): string[] {
3
+ const candidates = [obj[type]]
4
+
5
+ for (const c of candidates) {
6
+ if (Array.isArray(c) && c.length > 0) {
7
+ // 检查是否为对象数组,如果是则提取photo_name字段
8
+ if (typeof c[0] === 'object' && c[0] !== null) {
9
+ const ids = c.map((item: any) => {
10
+ const id = item?.photo_name || item?.id || item?.uid || item?.fileId || item?.value
11
+ || item?.response?.id || item?.response?.fileId || item?.resourceId
12
+ return id != null && id !== '' ? String(id) : null
13
+ }).filter((id: string | null) => id !== null)
14
+ return ids as string[]
15
+ }
16
+ // 如果是字符串数组,直接返回
17
+ return c as string[]
18
+ }
19
+ }
20
+ return []
21
+ }
@@ -1,23 +1,23 @@
1
- // 已移除类式 API,统一使用函数式 API
2
-
3
- // 模块级简化 API:按需绑定 window.__appBack,并更新接管状态
4
- let __moduleIntercept = false
5
-
6
- export function setAppBackIntercept(shouldIntercept: boolean): boolean {
7
- __moduleIntercept = !!shouldIntercept
8
- try {
9
- const w: any = window.__MICRO_APP_ENVIRONMENT__ ? (window as any).rawWindow as any : window as any
10
- // 若未绑定,则按需绑定;并打个标记,避免覆盖业务自定义实现
11
- if (!w.__appBack || typeof w.__appBack !== 'function' || !w.__appBack.__managedByAppBack) {
12
- const fn = () => __moduleIntercept
13
- ;(fn as any).__managedByAppBack = true
14
- w.__appBack = fn
15
- }
16
- }
17
- catch {}
18
- return __moduleIntercept
19
- }
20
-
21
- export function getAppBackIntercept(): boolean {
22
- return __moduleIntercept
23
- }
1
+ // 已移除类式 API,统一使用函数式 API
2
+
3
+ // 模块级简化 API:按需绑定 window.__appBack,并更新接管状态
4
+ let __moduleIntercept = false
5
+
6
+ export function setAppBackIntercept(shouldIntercept: boolean): boolean {
7
+ __moduleIntercept = !!shouldIntercept
8
+ try {
9
+ const w: any = window.__MICRO_APP_ENVIRONMENT__ ? (window as any).rawWindow as any : window as any
10
+ // 若未绑定,则按需绑定;并打个标记,避免覆盖业务自定义实现
11
+ if (!w.__appBack || typeof w.__appBack !== 'function' || !w.__appBack.__managedByAppBack) {
12
+ const fn = () => __moduleIntercept
13
+ ;(fn as any).__managedByAppBack = true
14
+ w.__appBack = fn
15
+ }
16
+ }
17
+ catch {}
18
+ return __moduleIntercept
19
+ }
20
+
21
+ export function getAppBackIntercept(): boolean {
22
+ return __moduleIntercept
23
+ }
@@ -1,38 +1,38 @@
1
- /**
2
- * 统一的返回函数 - 解决 micro-app 栈不同步导致 404 的问题
3
- *
4
- * 问题背景:
5
- * 1. 在 micro-app 环境中,Vue Router 的 router.back() 和浏览器的 history.back() 是独立的
6
- * 2. micro-app 维护了一个虚拟栈来跟踪子应用的路由历史
7
- * 3. 直接使用 router.back() 可能导致虚拟栈和浏览器 History 栈不同步
8
- * 4. 栈不同步会导致返回后 URL 跳转到不存在的页面(404)
9
- *
10
- * 解决方案:
11
- * - 在 micro-app 环境中使用 microApp.router.back()(由框架维护栈一致性)
12
- * - 在独立运行环境中使用 Vue Router 的 router.back()
13
- */
14
-
15
- import router from '@af-mobile-client-vue3/router'
16
-
17
- /**
18
- * 统一的返回函数
19
- * - micro-app 环境使用 microApp.router.back()
20
- * - 独立环境使用 router.back()
21
- * - 无浏览器历史时跳转到首页
22
- */
23
- export function goBack(): void {
24
- if (window.history.length <= 1) {
25
- console.log('[goBack] 无浏览器历史,跳转首页')
26
- router.push('/')
27
- return
28
- }
29
-
30
- if ((window as any).__MICRO_APP_ENVIRONMENT__) {
31
- console.log('[goBack] micro-app 环境,使用 microApp.router.back()')
32
- ;(window as any).microApp?.router?.back()
33
- }
34
- else {
35
- console.log('[goBack] 独立环境,使用 router.back()')
36
- router.back()
37
- }
38
- }
1
+ /**
2
+ * 统一的返回函数 - 解决 micro-app 栈不同步导致 404 的问题
3
+ *
4
+ * 问题背景:
5
+ * 1. 在 micro-app 环境中,Vue Router 的 router.back() 和浏览器的 history.back() 是独立的
6
+ * 2. micro-app 维护了一个虚拟栈来跟踪子应用的路由历史
7
+ * 3. 直接使用 router.back() 可能导致虚拟栈和浏览器 History 栈不同步
8
+ * 4. 栈不同步会导致返回后 URL 跳转到不存在的页面(404)
9
+ *
10
+ * 解决方案:
11
+ * - 在 micro-app 环境中使用 microApp.router.back()(由框架维护栈一致性)
12
+ * - 在独立运行环境中使用 Vue Router 的 router.back()
13
+ */
14
+
15
+ import router from '@af-mobile-client-vue3/router'
16
+
17
+ /**
18
+ * 统一的返回函数
19
+ * - micro-app 环境使用 microApp.router.back()
20
+ * - 独立环境使用 router.back()
21
+ * - 无浏览器历史时跳转到首页
22
+ */
23
+ export function goBack(): void {
24
+ if (window.history.length <= 1) {
25
+ console.log('[goBack] 无浏览器历史,跳转首页')
26
+ router.push('/')
27
+ return
28
+ }
29
+
30
+ if ((window as any).__MICRO_APP_ENVIRONMENT__) {
31
+ console.log('[goBack] micro-app 环境,使用 microApp.router.back()')
32
+ ;(window as any).microApp?.router?.back()
33
+ }
34
+ else {
35
+ console.log('[goBack] 独立环境,使用 router.back()')
36
+ router.back()
37
+ }
38
+ }
@@ -1,27 +1,27 @@
1
- // 时间工具:提供简单的日期时间格式化
2
-
3
- export function pad2(num: number): string {
4
- return num < 10 ? `0${num}` : `${num}`
5
- }
6
-
7
- /**
8
- * 按照简单占位符格式化当前时间
9
- * 支持占位:YYYY MM DD HH mm ss
10
- * @param format 默认 'YYYY-MM-DD HH:mm:ss'
11
- */
12
- export function formatNow(format: string = 'YYYY-MM-DD HH:mm:ss'): string {
13
- const d = new Date()
14
- const map: Record<string, string> = {
15
- YYYY: `${d.getFullYear()}`,
16
- MM: pad2(d.getMonth() + 1),
17
- DD: pad2(d.getDate()),
18
- HH: pad2(d.getHours()),
19
- mm: pad2(d.getMinutes()),
20
- ss: pad2(d.getSeconds()),
21
- }
22
- let out = format
23
- Object.keys(map).forEach((k) => {
24
- out = out.replace(new RegExp(k, 'g'), map[k])
25
- })
26
- return out
27
- }
1
+ // 时间工具:提供简单的日期时间格式化
2
+
3
+ export function pad2(num: number): string {
4
+ return num < 10 ? `0${num}` : `${num}`
5
+ }
6
+
7
+ /**
8
+ * 按照简单占位符格式化当前时间
9
+ * 支持占位:YYYY MM DD HH mm ss
10
+ * @param format 默认 'YYYY-MM-DD HH:mm:ss'
11
+ */
12
+ export function formatNow(format: string = 'YYYY-MM-DD HH:mm:ss'): string {
13
+ const d = new Date()
14
+ const map: Record<string, string> = {
15
+ YYYY: `${d.getFullYear()}`,
16
+ MM: pad2(d.getMonth() + 1),
17
+ DD: pad2(d.getDate()),
18
+ HH: pad2(d.getHours()),
19
+ mm: pad2(d.getMinutes()),
20
+ ss: pad2(d.getSeconds()),
21
+ }
22
+ let out = format
23
+ Object.keys(map).forEach((k) => {
24
+ out = out.replace(new RegExp(k, 'g'), map[k])
25
+ })
26
+ return out
27
+ }
@@ -1538,14 +1538,24 @@ function mergeSafeContentByTabAndType(templateJson: any[], safeContent: any[]):
1538
1538
 
1539
1539
  // 保存临时数据的函数
1540
1540
  async function saveDraftData() {
1541
- // 增加安检时间限制检查
1541
+ // 自定义校验
1542
+ let customRes: any
1543
+ if (safeConfig.value?.customLogic) {
1544
+ customRes = await runLogic(safeConfig.value?.customLogic, { serverStartTime: onSiteDate.value }, 'af-safecheck')
1545
+ if (customRes && customRes?.code !== 200 && customRes?.msg) {
1546
+ showToast(customRes?.msg || '自定义校验失败')
1547
+ return
1548
+ }
1549
+ }
1550
+
1542
1551
  if (safeConfig.value?.isTimer && !isReadOnly.value) {
1543
1552
  const limitTime = safeConfig.value?.limitTime || 10
1544
- if (elapsedSeconds.value < (limitTime * 60)) {
1553
+ if (customRes?.timeLimitCheck === 'fail' && elapsedSeconds.value < (limitTime * 60)) {
1545
1554
  showToast(`安检时间必须大于${limitTime}分钟`)
1546
1555
  return
1547
1556
  }
1548
1557
  }
1558
+
1549
1559
  showConfirmDialog({
1550
1560
  title: '确认保存',
1551
1561
  message: '是否保存当前未提交数据?',
@@ -1614,27 +1624,28 @@ async function onSubmit() {
1614
1624
  return
1615
1625
  }
1616
1626
 
1617
- if (safeConfig.value?.isTimer && !isReadOnly.value) {
1618
- const limitTime = safeConfig.value?.limitTime || 10
1619
- if (elapsedSeconds.value < (limitTime * 60)) {
1620
- showToast(`安检时间必须大于${limitTime}分钟`)
1621
- return
1622
- }
1623
- }
1624
-
1625
1627
  // 用户确认提交,组织提交数据
1626
1628
  const submitData = await organizeSubmitData()
1627
1629
  console.log('提交数据:', submitData)
1628
1630
 
1629
1631
  // 自定义校验
1632
+ let customRes: any
1630
1633
  if (safeConfig.value?.customLogic) {
1631
- const customRes: any = await runLogic(safeConfig.value?.customLogic, { paperData: submitData, changeTableData: safecheckStore.getChangeTableId() }, 'af-safecheck')
1634
+ customRes = await runLogic(safeConfig.value?.customLogic, { paperData: submitData, changeTableData: safecheckStore.getChangeTableId(), serverStartTime: onSiteDate.value }, 'af-safecheck')
1632
1635
  if (customRes && customRes?.code !== 200 && customRes?.msg) {
1633
1636
  showToast(customRes?.msg || '自定义校验失败')
1634
1637
  return
1635
1638
  }
1636
1639
  }
1637
1640
 
1641
+ if (safeConfig.value?.isTimer && !isReadOnly.value) {
1642
+ const limitTime = safeConfig.value?.limitTime || 10
1643
+ if (customRes?.timeLimitCheck === 'fail' && elapsedSeconds.value < (limitTime * 60)) {
1644
+ showToast(`安检时间必须大于${limitTime}分钟`)
1645
+ return
1646
+ }
1647
+ }
1648
+
1638
1649
  // 如果所有表单校验通过,则弹出确认框
1639
1650
  showConfirmDialog({
1640
1651
  title: '安检单填写',
@@ -7,7 +7,7 @@ import upaddress from './upaddress.vue'
7
7
 
8
8
  const props = withDefaults(defineProps<{
9
9
  id?: string
10
- userDetail?: object | any
10
+ userDetail?: Record<string, any>
11
11
  isReadOnly?: boolean
12
12
  }>(), {
13
13
  id: '',
@@ -11,7 +11,7 @@ const workflowId: string = '6149'
11
11
  const stepId: string = '5'
12
12
 
13
13
  // 基础组件引用
14
- const stepDetailBaseRef = ref<InstanceType<typeof StepDetailBase>>()
14
+ const stepDetailBaseRef = ref<InstanceType<typeof StepDetailBase>>()
15
15
  </script>
16
16
 
17
17
  <template>
@@ -1,12 +1,15 @@
1
1
  <script setup lang="ts">
2
2
  import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
3
  import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
-
5
4
  import router from '@af-mobile-client-vue3/router'
5
+ import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
6
+ import {
7
+ Button as VanButton,
8
+ } from 'vant'
6
9
  import { ref } from 'vue'
7
10
 
8
- const configName = ref('AddConstructionForm')
9
- const serviceName = ref('af-linepatrol')
11
+ const configName = ref('SecurityPhotoForm')
12
+ const serviceName = ref('af-safecheck')
10
13
 
11
14
  const formGroupAddConstruction = ref<any>(null)
12
15
  function sleep(ms) {
@@ -32,12 +35,21 @@ function onAddressChange(data: any) {
32
35
  function onRegionChange(data: any) {
33
36
  console.warn('表单新增数据变化', data)
34
37
  }
38
+ function cli(data: any) {
39
+ mobileUtil.execute({
40
+ funcName: 'exportDatabase',
41
+ param: { a: 1 },
42
+ callbackFunc: (result) => {
43
+ console.log('回调了test111', result)
44
+ },
45
+ })
46
+ }
35
47
  </script>
36
48
 
37
49
  <template>
38
50
  <NormalDataLayout id="XFormGroupView" title="纯表单">
39
51
  <template #layout_content>
40
- <XForm
52
+ <!-- <XForm
41
53
  ref="formGroupAddConstruction"
42
54
  mode="新增"
43
55
  :config-name="configName"
@@ -46,7 +58,8 @@ function onRegionChange(data: any) {
46
58
  @address-change="onAddressChange"
47
59
  @region-change="onRegionChange"
48
60
  @on-submit="onSubmit"
49
- />
61
+ />-->
62
+ <VanButton type="default" plain icon="arrow-left" size="small" @click="cli" />
50
63
  </template>
51
64
  </NormalDataLayout>
52
65
  </template>
@@ -174,14 +174,15 @@ function deleteCacheImages() {
174
174
  param: {},
175
175
  funcName: 'checkUploadQueue',
176
176
  callbackFunc: (res?: any) => {
177
- console.log('检查是否符合清除条件', res)
178
- if (res?.data?.codeFlag === 200) {
179
- showToast('清除成功!')
180
- }
181
- else if (res?.data?.codeFlag === 700) {
177
+ if (res?.data?.codeFlag === 700) {
182
178
  confirmDelete()
183
179
  }
184
- else { /* empty */ }
180
+ else if (res?.status === 'success' || res?.data?.codeFlag === 200) {
181
+ showToast('清理图片缓存成功!')
182
+ }
183
+ else {
184
+ showToast('清理图片缓存失败!')
185
+ }
185
186
  },
186
187
  })
187
188
  }
@@ -199,10 +200,12 @@ function confirmDelete() {
199
200
  funcName: 'clearLocalImages',
200
201
  callbackFunc: (res?: any) => {
201
202
  console.log('清除本地缓存返回', res)
202
- if (res?.data?.codeFlag === 200) {
203
- showToast('清除成功!')
203
+ if (res?.status === 'success' || res?.data?.codeFlag === 200) {
204
+ showToast('清理图片缓存成功!')
205
+ }
206
+ else {
207
+ showToast('清理图片缓存失败!')
204
208
  }
205
- else { /* empty */ }
206
209
  },
207
210
  })
208
211
  })
@@ -210,6 +213,21 @@ function confirmDelete() {
210
213
  // on cancel
211
214
  })
212
215
  }
216
+
217
+ function exportDatabase() {
218
+ mobileUtil.execute({
219
+ param: {},
220
+ funcName: 'exportDatabase',
221
+ callbackFunc: (res?: any) => {
222
+ if (res?.status === 'success' || res?.data?.codeFlag === 200) {
223
+ showToast('反馈成功!')
224
+ }
225
+ else {
226
+ showToast('反馈异常,请联系管理人员!')
227
+ }
228
+ },
229
+ })
230
+ }
213
231
  </script>
214
232
 
215
233
  <template>
@@ -311,17 +329,24 @@ function confirmDelete() {
311
329
  @update:model-value="handleSystemSoundSwitchChange"
312
330
  />
313
331
  </div>
314
- <div class="menu-item" @click="exit_login">
332
+ <div class="menu-item" @click="deleteCacheImages">
315
333
  <div class="menu-item-content">
316
- <VanIcon name="sign" class="menu-icon logout-icon" />
317
- <span class="menu-text">退出登录</span>
334
+ <VanIcon name="delete" class="menu-icon logout-icon" />
335
+ <span class="menu-text">清理图片缓存</span>
318
336
  </div>
319
337
  <VanIcon name="arrow" class="menu-arrow" />
320
338
  </div>
321
- <div v-if="setting.getSetting()?.showDeleteCacheImages" class="menu-item" @click="deleteCacheImages">
339
+ <div class="menu-item" @click="exportDatabase">
322
340
  <div class="menu-item-content">
323
- <VanIcon name="delete" class="menu-icon logout-icon" />
324
- <span class="menu-text">清除本地缓存图片</span>
341
+ <VanIcon name="records" class="menu-icon" />
342
+ <span class="menu-text">反馈本地数据</span>
343
+ </div>
344
+ <VanIcon name="arrow" class="menu-arrow" />
345
+ </div>
346
+ <div class="menu-item" @click="exit_login">
347
+ <div class="menu-item-content">
348
+ <VanIcon name="sign" class="menu-icon logout-icon" />
349
+ <span class="menu-text">退出登录</span>
325
350
  </div>
326
351
  <VanIcon name="arrow" class="menu-arrow" />
327
352
  </div>
package/vite.config.ts CHANGED
@@ -11,7 +11,7 @@ export default ({ mode }: ConfigEnv): UserConfig => {
11
11
 
12
12
  const appProxys = {}
13
13
 
14
- const v4Server = 'http://192.168.50.67:31567'
14
+ const v4Server = 'http://aote-office.8866.org:31577'
15
15
  const v3Server = 'http://192.168.50.67:31567'
16
16
  const OSSServerDev = 'http://192.168.50.67:30351'
17
17
  const geoserver = 'http://192.168.50.67:31567'