af-mobile-client-vue3 1.6.56 → 1.6.58
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 +1 -1
- package/public//346/212/200/346/234/257/345/210/206/346/236/220.txt +123 -0
- package/src/components/core/ImageUploader/index.vue +29 -13
- package/src/components/core/Signature/SignatureComponent.vue +18 -2
- package/src/components/core/XMultiSelect/index.vue +15 -32
- package/src/components/core/XSelect/index.vue +14 -29
- package/src/components/data/XForm/index.vue +6 -1
- package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
- package/src/components/data/XReportGrid/print.js +184 -184
- package/src/components/data/contract/addcontract.vue +263 -263
- package/src/components/data/contract/index.vue +43 -43
- package/src/components/data/contract/viewContract.vue +22 -22
- package/src/stores/modules/safecheckStore.ts +47 -47
- package/src/utils/PhotoClean.ts +21 -21
- package/src/utils/appBackManager.ts +23 -23
- package/src/utils/driving/drivingUtils.ts +158 -158
- package/src/utils/mobileUtil.ts +1 -0
- package/src/utils/safeBack.ts +38 -38
- package/src/utils/timeUtil.ts +27 -27
- package/src/views/SafeInspection/SecurityCertificate/userInfo/index.vue +18 -3
- package/src/views/SafeInspection/SecurityFormItem/CameraView/index.vue +17 -2
- package/src/views/component/Driving/index.vue +127 -127
- package/src/views/component/XFormView/index.vue +50 -11
- package/src/views/user/my/comm/ModifyPassword.vue +11 -2
- package/src/views/user/my/index.vue +47 -35
- package/vite.config.ts +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
三方系统实现:
|
|
2
|
+
前端框架:vue2.0+ element-ui
|
|
3
|
+
后端框架:java Spring Boot
|
|
4
|
+
App框架:原生安卓框架+H5
|
|
5
|
+
关系数据库:PostgreSQL(开源)
|
|
6
|
+
GIS开发组件:SuperMap(超图,国产),中城燃气所属集团提供超图平台服务
|
|
7
|
+
时序数据库:Elasticsearch(存储坐标数据)
|
|
8
|
+
消息中间件:rabbitmq
|
|
9
|
+
文件服务器:minio
|
|
10
|
+
缓存中间件:redis
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 第三方系统接入技术对接清单
|
|
14
|
+
|
|
15
|
+
## 一、前端(micro-app子应用接入)
|
|
16
|
+
|
|
17
|
+
### 1.1 第三方前端改造
|
|
18
|
+
- [ ] 第三方项目 Vue 版本升级(建议 Vue 2.7+)
|
|
19
|
+
- [ ] 第三方项目构建工具迁移至 Vite
|
|
20
|
+
- [ ] 第三方项目路由模式改为 history 模式
|
|
21
|
+
- [ ] 第三方项目添加 basename 配置
|
|
22
|
+
- [ ] 第三方项目实现 micro-app 生命周期钩子(bootstrap/mount/unmount)
|
|
23
|
+
- [ ] 第三方项目移除独立登录页,改为接收主应用传递的登录态
|
|
24
|
+
- [ ] 第三方项目样式隔离(避免与主应用样式冲突)
|
|
25
|
+
|
|
26
|
+
### 1.2 主应用改造
|
|
27
|
+
- [ ] 主应用注册第三方子应用(microApps.ts 配置)
|
|
28
|
+
- [ ] 主应用创建第三方子应用渲染页面
|
|
29
|
+
- [ ] 主应用封装第三方 API 代理服务
|
|
30
|
+
- [ ] 主应用配置第三方子应用路由
|
|
31
|
+
- [ ] 主应用处理第三方子应用生命周期回调
|
|
32
|
+
- [ ] 主应用实现与第三方子应用的数据通信机制
|
|
33
|
+
- [ ] 主应用配置第三方子应用跨域策略
|
|
34
|
+
|
|
35
|
+
### 1.3 第三方 API 代理
|
|
36
|
+
- [ ] 主应用封装第三方业务 API 代理方法
|
|
37
|
+
- [ ] 主应用封装第三方文件上传接口
|
|
38
|
+
- [ ] 主应用封装第三方数据查询接口
|
|
39
|
+
- [ ] 代理接口统一添加主系统 Token 认证
|
|
40
|
+
- [ ] 代理接口统一处理登录过期跳转
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 二、后端(鉴权相关)
|
|
45
|
+
|
|
46
|
+
### 2.1 主系统后端改造
|
|
47
|
+
- [ ] 新增第三方系统白名单配置(系统编码、密钥、IP)
|
|
48
|
+
- [ ] 新增第三方用户 Token 绑定接口
|
|
49
|
+
- [ ] 新增第三方用户刷新 Token 接口
|
|
50
|
+
- [ ] 新增第三方用户信息查询接口
|
|
51
|
+
- [ ] 新增网关信任来源过滤器
|
|
52
|
+
- [ ] 网关层支持 X-Third-Party-User-Id 请求头识别
|
|
53
|
+
|
|
54
|
+
### 2.2 API 网关/路由配置
|
|
55
|
+
- [ ] 配置第三方系统 API 路由转发规则
|
|
56
|
+
- [ ] 配置第三方静态资源路径映射
|
|
57
|
+
- [ ] 配置跨域访问策略
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 三、认证方案选择
|
|
62
|
+
|
|
63
|
+
### 推荐方案:代理模式(第三方不改登录)
|
|
64
|
+
- [ ] 主应用前端统一管理 Token
|
|
65
|
+
- [ ] 第三方子应用通过主应用代理调用主系统 API
|
|
66
|
+
- [ ] 第三方登录完成后跳转主应用页面,由主应用注入登录态
|
|
67
|
+
|
|
68
|
+
### 备选方案:Token 映射模式
|
|
69
|
+
- [ ] 主系统提供第三方 Token 换取接口
|
|
70
|
+
- [ ] 主系统维护第三方用户与本系统用户映射关系
|
|
71
|
+
- [ ] 第三方登录后自动调接口换取主系统 Token
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 四、数据对接
|
|
76
|
+
|
|
77
|
+
### 4.1 用户数据
|
|
78
|
+
- [ ] 确定用户数据同步策略(共享表 / API 调用 / DB Link)
|
|
79
|
+
- [ ] 第三方用户与主系统用户绑定关系设计
|
|
80
|
+
|
|
81
|
+
### 4.2 业务数据
|
|
82
|
+
- [ ] 梳理需要主系统提供的业务数据接口
|
|
83
|
+
- [ ] 梳理需要提供给第三方的业务数据接口
|
|
84
|
+
|
|
85
|
+
### 4.3 文件服务
|
|
86
|
+
- [ ] 确认是否复用主系统 MinIO 文件服务
|
|
87
|
+
- [ ] 配置第三方文件上传白名单
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 五、GIS 地图对接(如需要)
|
|
92
|
+
- [ ] 确认 SuperMap 版本和接口规范
|
|
93
|
+
- [ ] 主应用封装地图加载组件
|
|
94
|
+
- [ ] 主应用与第三方子应用地图实例共享方案
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 六、联调测试
|
|
99
|
+
- [ ] 第三方子应用独立运行测试
|
|
100
|
+
- [ ] 第三方子应用嵌入主应用测试
|
|
101
|
+
- [ ] 第三方调用主系统 API 联调
|
|
102
|
+
- [ ] 主系统 Token 有效性验证
|
|
103
|
+
- [ ] 子应用间跳转和返回测试
|
|
104
|
+
- [ ] 登录态同步测试
|
|
105
|
+
- [ ] 性能测试(加载时间、内存占用)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 七、部署上线
|
|
110
|
+
- [ ] 第三方子应用构建配置调整
|
|
111
|
+
- [ ] 生产环境域名解析配置
|
|
112
|
+
- [ ] Nginx / API 网关路由配置
|
|
113
|
+
- [ ] 主系统 API 跨域配置
|
|
114
|
+
- [ ] 第三方系统白名单生产配置
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 八、注意事项
|
|
119
|
+
- 第三方前端不能有独立的登录页面
|
|
120
|
+
- 第三方前端不能直接存储 Token
|
|
121
|
+
- 第三方前端所有 API 请求需通过主应用代理
|
|
122
|
+
- 需要确认第三方项目的具体版本和配置
|
|
123
|
+
- 需要确认双方 API 接口文档和数据字典
|
|
@@ -24,17 +24,36 @@ interface WatermarkConfig {
|
|
|
24
24
|
blurThreshold?: string | number
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
imageList
|
|
29
|
-
outerIndex
|
|
30
|
-
authority
|
|
31
|
-
uploadMode
|
|
32
|
-
attr
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
interface ImageUploaderProps {
|
|
28
|
+
imageList?: any[]
|
|
29
|
+
outerIndex?: number | undefined
|
|
30
|
+
authority?: string
|
|
31
|
+
uploadMode?: string
|
|
32
|
+
attr?: {
|
|
33
|
+
addOrEdit?: string
|
|
34
|
+
acceptCount?: number
|
|
35
|
+
minAcceptCount?: number
|
|
36
|
+
uploadImage?: boolean
|
|
37
|
+
watermark?: WatermarkConfig
|
|
38
|
+
useType?: string
|
|
39
|
+
}
|
|
40
|
+
mode?: string
|
|
41
|
+
serviceName?: string
|
|
42
|
+
readonly?: boolean
|
|
43
|
+
isAsyncUpload?: boolean
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const props = withDefaults(defineProps<ImageUploaderProps>(), {
|
|
47
|
+
imageList: () => [],
|
|
48
|
+
outerIndex: undefined,
|
|
49
|
+
authority: 'user',
|
|
50
|
+
uploadMode: 'server',
|
|
51
|
+
attr: () => ({}),
|
|
52
|
+
mode: '新增',
|
|
53
|
+
serviceName: '',
|
|
35
54
|
// 整体只读:只允许预览,禁止拍照/上传/删除
|
|
36
|
-
readonly:
|
|
37
|
-
isAsyncUpload:
|
|
55
|
+
readonly: false,
|
|
56
|
+
isAsyncUpload: false,
|
|
38
57
|
})
|
|
39
58
|
const emit = defineEmits(['updateFileList', 'updateAllFileList', 'photoQualityChange'])
|
|
40
59
|
|
|
@@ -51,9 +70,6 @@ const parentCommonId = (() => {
|
|
|
51
70
|
}
|
|
52
71
|
})()
|
|
53
72
|
|
|
54
|
-
// 浏览器 / 微信内 H5:统一用隐藏 file input(与单独 camera input 行为等价,均为系统选图)
|
|
55
|
-
// const fileInputRef = ref<HTMLInputElement | undefined>()
|
|
56
|
-
const parentData: any = inject('provideParent')
|
|
57
73
|
// 浏览器 / 微信内 H5:统一用隐藏 file input(与单独 camera input 行为等价,均为系统选图)
|
|
58
74
|
const fileInputRef = ref<HTMLInputElement | undefined>()
|
|
59
75
|
|
|
@@ -19,10 +19,26 @@ const emit = defineEmits<{
|
|
|
19
19
|
signatureComplete: [data: any]
|
|
20
20
|
}>()
|
|
21
21
|
|
|
22
|
+
// 从父组件获取 commonId,仅读取字符串值,不持有父级 provideParent 对象
|
|
23
|
+
const parentCommonId = (() => {
|
|
24
|
+
try {
|
|
25
|
+
const parent = inject<any>('provideParent', undefined)
|
|
26
|
+
console.log('parent==', parent)
|
|
27
|
+
if (!parent) {
|
|
28
|
+
return ''
|
|
29
|
+
}
|
|
30
|
+
if (typeof parent.commonId === 'object' && parent.commonId && 'value' in parent.commonId) {
|
|
31
|
+
return String(parent.commonId.value ?? '')
|
|
32
|
+
}
|
|
33
|
+
return String(parent.commonId ?? '')
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return ''
|
|
37
|
+
}
|
|
38
|
+
})()
|
|
22
39
|
const signatureImage = ref<string>('')
|
|
23
40
|
const rawBase64Data = ref<string>('') // 保存原始base64数据
|
|
24
41
|
const hasSignature = ref(false)
|
|
25
|
-
const parentData: any = inject('provideParent')
|
|
26
42
|
const imageList = ref<Array<any>>(props.imageList ?? [])
|
|
27
43
|
console.log('imageList', imageList.value)
|
|
28
44
|
console.log('props.imageList', props.imageList)
|
|
@@ -79,7 +95,7 @@ function handleSignature() {
|
|
|
79
95
|
f_operator: 'server',
|
|
80
96
|
imgPath: result.data.filePath,
|
|
81
97
|
urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
|
|
82
|
-
commonId:
|
|
98
|
+
commonId: parentCommonId,
|
|
83
99
|
}
|
|
84
100
|
if (props.isAsyncUpload) {
|
|
85
101
|
// 添加上传队列
|
|
@@ -10,38 +10,20 @@ import {
|
|
|
10
10
|
} from 'vant'
|
|
11
11
|
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
|
12
12
|
|
|
13
|
-
const props = defineProps
|
|
14
|
-
columns
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
type: Object,
|
|
28
|
-
default() {
|
|
29
|
-
return { text: 'label', value: 'value' }
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
// 是否支持搜索
|
|
33
|
-
isSearch: {
|
|
34
|
-
type: Boolean,
|
|
35
|
-
default: true,
|
|
36
|
-
},
|
|
37
|
-
lazyLoad: { // 是否启用懒加载
|
|
38
|
-
type: String,
|
|
39
|
-
default: 'false',
|
|
40
|
-
},
|
|
41
|
-
onSearch: { // 懒加载时的搜索函数
|
|
42
|
-
type: Function,
|
|
43
|
-
default: null,
|
|
44
|
-
},
|
|
13
|
+
const props = withDefaults(defineProps<{
|
|
14
|
+
columns?: any[]
|
|
15
|
+
selectValue?: any[]
|
|
16
|
+
option?: Record<string, string>
|
|
17
|
+
isSearch?: boolean // 是否支持搜索
|
|
18
|
+
lazyLoad?: string // 是否启用懒加载
|
|
19
|
+
onSearch?: ((searchValue: string) => Promise<any[]>) | null // 懒加载时的搜索函数
|
|
20
|
+
}>(), {
|
|
21
|
+
columns: () => [],
|
|
22
|
+
selectValue: () => [],
|
|
23
|
+
option: () => ({ text: 'label', value: 'value' }),
|
|
24
|
+
isSearch: true,
|
|
25
|
+
lazyLoad: 'false',
|
|
26
|
+
onSearch: null,
|
|
45
27
|
})
|
|
46
28
|
const emits = defineEmits(['input', 'confirm', 'change', 'cancel'])
|
|
47
29
|
const show = ref(false)
|
|
@@ -130,6 +112,7 @@ const stopWatchCheckboxValue = watch(() => checkboxValue.value.length, (newVal,
|
|
|
130
112
|
|
|
131
113
|
onBeforeUnmount(() => {
|
|
132
114
|
stopWatchCheckboxValue()
|
|
115
|
+
show.value = false
|
|
133
116
|
})
|
|
134
117
|
const resultLabel = computed(() => {
|
|
135
118
|
const res = props.columns.filter((item) => {
|
|
@@ -7,35 +7,20 @@ import {
|
|
|
7
7
|
} from 'vant'
|
|
8
8
|
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
|
9
9
|
|
|
10
|
-
const props = defineProps
|
|
11
|
-
columns
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
type: Boolean,
|
|
25
|
-
default: false,
|
|
26
|
-
},
|
|
27
|
-
border: { // 是否展示边框
|
|
28
|
-
type: Boolean,
|
|
29
|
-
default: false,
|
|
30
|
-
},
|
|
31
|
-
lazyLoad: { // 是否启用懒加载
|
|
32
|
-
type: String,
|
|
33
|
-
default: 'false',
|
|
34
|
-
},
|
|
35
|
-
onSearch: { // 懒加载时的搜索函数
|
|
36
|
-
type: Function,
|
|
37
|
-
default: null,
|
|
38
|
-
},
|
|
10
|
+
const props = withDefaults(defineProps<{
|
|
11
|
+
columns?: any[]
|
|
12
|
+
option?: Record<string, string>
|
|
13
|
+
offOption?: boolean
|
|
14
|
+
border?: boolean
|
|
15
|
+
lazyLoad?: string
|
|
16
|
+
onSearch?: ((searchValue: string) => Promise<any[]>) | null
|
|
17
|
+
}>(), {
|
|
18
|
+
columns: () => [],
|
|
19
|
+
option: () => ({ text: 'label', value: 'value', children: 'children' }),
|
|
20
|
+
offOption: false,
|
|
21
|
+
border: false,
|
|
22
|
+
lazyLoad: 'false',
|
|
23
|
+
onSearch: null,
|
|
39
24
|
})
|
|
40
25
|
const emits = defineEmits(['confirm', 'change', 'cancel', 'input'])
|
|
41
26
|
const show = ref(false)
|
|
@@ -107,6 +107,7 @@ const rules = reactive({})
|
|
|
107
107
|
const myGetDataParams = ref({})
|
|
108
108
|
const isKeyHandle = ref(false)
|
|
109
109
|
const submitLoading = ref(false)
|
|
110
|
+
let navigateTimer: number | null = null
|
|
110
111
|
|
|
111
112
|
// 配置相关状态
|
|
112
113
|
const formConfig = ref<GroupFormItems | null>(null)
|
|
@@ -392,6 +393,10 @@ onBeforeUnmount(() => {
|
|
|
392
393
|
stopWatchPreviewMapPoint?.()
|
|
393
394
|
stopWatchFormData?.()
|
|
394
395
|
stopWatchForm?.()
|
|
396
|
+
if (navigateTimer) {
|
|
397
|
+
window.clearTimeout(navigateTimer)
|
|
398
|
+
navigateTimer = null
|
|
399
|
+
}
|
|
395
400
|
})
|
|
396
401
|
|
|
397
402
|
// 支持函数调用方式初始化
|
|
@@ -696,7 +701,7 @@ async function onSubmit() {
|
|
|
696
701
|
showFailToast('提交失败!!')
|
|
697
702
|
}
|
|
698
703
|
finally {
|
|
699
|
-
setTimeout(() => {
|
|
704
|
+
navigateTimer = window.setTimeout(() => {
|
|
700
705
|
history.back()
|
|
701
706
|
}, 1000)
|
|
702
707
|
}
|
|
@@ -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>
|