af-mobile-client-vue3 1.6.46 → 1.6.48
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/src/components/core/ImageUploader/index.vue +2 -0
- package/src/components/data/FilePreview/index.vue +76 -9
- package/src/utils/fileType.ts +11 -5
- package/src/views/SafeInspection/SecurityCertificate/index.vue +8 -2
- package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/components/PhotoCaptureCard.vue +6 -1
- package/src/views/SafeInspection/SecurityCertificate/photoAiRecognition/index.vue +7 -0
- package/src/views/SafeInspection/SecurityFormItem/CameraView/index.vue +3 -0
package/package.json
CHANGED
|
@@ -21,6 +21,7 @@ interface WatermarkConfig {
|
|
|
21
21
|
format?: string
|
|
22
22
|
customLines?: string[]
|
|
23
23
|
enableRePhotoCheck?: boolean
|
|
24
|
+
blurThreshold?: string | number
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const props = defineProps({
|
|
@@ -180,6 +181,7 @@ function triggerCamera() {
|
|
|
180
181
|
if (watermark.alpha !== undefined && String(watermark.alpha) !== '')
|
|
181
182
|
param.watermarkAlpha = watermark.alpha
|
|
182
183
|
}
|
|
184
|
+
param.blurThreshold = (props.attr as any)?.watermark?.blurThreshold ?? 30
|
|
183
185
|
return param
|
|
184
186
|
})(),
|
|
185
187
|
callbackFunc: (result: any) => {
|
|
@@ -40,6 +40,7 @@ const fileSource = shallowRef<string | ArrayBuffer>('')
|
|
|
40
40
|
const textContent = ref('')
|
|
41
41
|
const imageSrc = ref('')
|
|
42
42
|
const videoSrc = ref('')
|
|
43
|
+
const audioSrc = ref('')
|
|
43
44
|
const openUrl = ref('')
|
|
44
45
|
const downloadName = ref('')
|
|
45
46
|
const loading = ref(false)
|
|
@@ -66,24 +67,36 @@ async function init(options: FilePreviewInitOptions) {
|
|
|
66
67
|
fileSource.value = ''
|
|
67
68
|
imageSrc.value = ''
|
|
68
69
|
videoSrc.value = ''
|
|
70
|
+
audioSrc.value = ''
|
|
69
71
|
|
|
70
72
|
try {
|
|
71
73
|
switch (previewKind.value) {
|
|
72
74
|
case 'image':
|
|
73
75
|
imageSrc.value = openUrl.value
|
|
74
76
|
break
|
|
77
|
+
|
|
75
78
|
case 'video':
|
|
76
79
|
videoSrc.value = openUrl.value
|
|
77
80
|
break
|
|
81
|
+
|
|
82
|
+
case 'audio':
|
|
83
|
+
audioSrc.value = openUrl.value
|
|
84
|
+
break
|
|
85
|
+
|
|
78
86
|
case 'text':
|
|
79
87
|
textContent.value = await fetchResourceText(openUrl.value)
|
|
80
88
|
break
|
|
89
|
+
|
|
81
90
|
case 'pdf':
|
|
82
91
|
case 'docx':
|
|
92
|
+
case 'doc':
|
|
83
93
|
case 'xlsx':
|
|
94
|
+
case 'xls':
|
|
84
95
|
fileSource.value = await fetchResourceArrayBuffer(openUrl.value)
|
|
85
96
|
break
|
|
86
|
-
|
|
97
|
+
|
|
98
|
+
case 'unsupported':
|
|
99
|
+
// 未知格式,直接用 iframe 尝试打开,无需预加载内容
|
|
87
100
|
break
|
|
88
101
|
}
|
|
89
102
|
}
|
|
@@ -95,11 +108,6 @@ async function init(options: FilePreviewInitOptions) {
|
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
|
|
98
|
-
function openExternal() {
|
|
99
|
-
if (openUrl.value)
|
|
100
|
-
window.open(openUrl.value, '_blank')
|
|
101
|
-
}
|
|
102
|
-
|
|
103
111
|
function handleDownload() {
|
|
104
112
|
if (!openUrl.value)
|
|
105
113
|
return
|
|
@@ -139,14 +147,16 @@ defineExpose({
|
|
|
139
147
|
class="office-preview"
|
|
140
148
|
@error="onRenderError"
|
|
141
149
|
/>
|
|
150
|
+
<!-- docx / doc 共用同一渲染器 -->
|
|
142
151
|
<VueOfficeDocx
|
|
143
|
-
v-else-if="previewKind === 'docx' && fileSource"
|
|
152
|
+
v-else-if="(previewKind === 'docx' || previewKind === 'doc') && fileSource"
|
|
144
153
|
:src="fileSource"
|
|
145
154
|
class="office-preview"
|
|
146
155
|
@error="onRenderError"
|
|
147
156
|
/>
|
|
157
|
+
<!-- xlsx / xls 共用同一渲染器 -->
|
|
148
158
|
<VueOfficeExcel
|
|
149
|
-
v-else-if="previewKind === 'xlsx' && fileSource"
|
|
159
|
+
v-else-if="(previewKind === 'xlsx' || previewKind === 'xls') && fileSource"
|
|
150
160
|
:src="fileSource"
|
|
151
161
|
class="office-preview"
|
|
152
162
|
@error="onRenderError"
|
|
@@ -157,8 +167,26 @@ defineExpose({
|
|
|
157
167
|
<div v-else-if="previewKind === 'video'" class="preview-video-wrapper">
|
|
158
168
|
<video class="preview-video" controls :src="videoSrc" />
|
|
159
169
|
</div>
|
|
170
|
+
<div v-else-if="previewKind === 'audio'" class="preview-audio-wrapper">
|
|
171
|
+
<audio class="preview-audio" controls :src="audioSrc" />
|
|
172
|
+
</div>
|
|
160
173
|
<pre v-else-if="previewKind === 'text'" class="preview-text">{{ textContent }}</pre>
|
|
161
|
-
|
|
174
|
+
<!-- 未知格式:用 iframe 尝试直接打开,系统/浏览器自行决定如何处理 -->
|
|
175
|
+
<div v-else-if="previewKind === 'unsupported'" class="preview-iframe-wrapper">
|
|
176
|
+
<iframe
|
|
177
|
+
:src="openUrl"
|
|
178
|
+
class="preview-iframe"
|
|
179
|
+
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
|
|
180
|
+
@error="onRenderError"
|
|
181
|
+
/>
|
|
182
|
+
<div class="preview-iframe-fallback">
|
|
183
|
+
<span>若文件无法显示,请</span>
|
|
184
|
+
<VanButton size="small" type="primary" plain @click="handleDownload">
|
|
185
|
+
下载查看
|
|
186
|
+
</VanButton>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
<VanEmpty v-else description="文件路径异常">
|
|
162
190
|
<VanButton v-if="openUrl" size="small" type="primary" @click="handleDownload">
|
|
163
191
|
下载
|
|
164
192
|
</VanButton>
|
|
@@ -232,4 +260,43 @@ defineExpose({
|
|
|
232
260
|
line-height: 1.5;
|
|
233
261
|
color: #333;
|
|
234
262
|
}
|
|
263
|
+
|
|
264
|
+
.preview-audio-wrapper {
|
|
265
|
+
display: flex;
|
|
266
|
+
align-items: center;
|
|
267
|
+
justify-content: center;
|
|
268
|
+
padding: 32px 16px;
|
|
269
|
+
min-height: 120px;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.preview-audio {
|
|
273
|
+
width: 100%;
|
|
274
|
+
max-width: 480px;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.preview-iframe-wrapper {
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-direction: column;
|
|
280
|
+
width: 100%;
|
|
281
|
+
height: 100%;
|
|
282
|
+
flex: 1;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.preview-iframe {
|
|
286
|
+
width: 100%;
|
|
287
|
+
flex: 1;
|
|
288
|
+
min-height: 200px;
|
|
289
|
+
border: none;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.preview-iframe-fallback {
|
|
293
|
+
display: flex;
|
|
294
|
+
align-items: center;
|
|
295
|
+
gap: 8px;
|
|
296
|
+
padding: 8px 12px;
|
|
297
|
+
font-size: 12px;
|
|
298
|
+
color: #999;
|
|
299
|
+
flex-shrink: 0;
|
|
300
|
+
border-top: 1px solid #f0f0f0;
|
|
301
|
+
}
|
|
235
302
|
</style>
|
package/src/utils/fileType.ts
CHANGED
|
@@ -68,22 +68,28 @@ export function getFileTypeMeta(name?: string): FileTypeMeta {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export type PreviewFileKind = 'pdf' | 'docx' | 'xlsx' | 'image' | 'video' | 'text' | 'unsupported'
|
|
71
|
+
export type PreviewFileKind = 'pdf' | 'docx' | 'doc' | 'xlsx' | 'xls' | 'image' | 'video' | 'audio' | 'text' | 'unsupported'
|
|
72
72
|
|
|
73
73
|
/** 附件预览类型(vue-office / 原生标签) */
|
|
74
74
|
export function getPreviewFileKind(name?: string): PreviewFileKind {
|
|
75
75
|
const ext = getFileExtension(name)
|
|
76
76
|
if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'ico', 'tif', 'tiff', 'avif'].includes(ext))
|
|
77
77
|
return 'image'
|
|
78
|
-
if (['mp4', 'webm', 'mov', 'm4v'].includes(ext))
|
|
78
|
+
if (['mp4', 'webm', 'mov', 'm4v', 'avi', 'mkv', 'flv', 'rmvb'].includes(ext))
|
|
79
79
|
return 'video'
|
|
80
|
+
if (['mp3', 'wav', 'ogg', 'aac', 'flac', 'm4a', 'wma'].includes(ext))
|
|
81
|
+
return 'audio'
|
|
80
82
|
if (ext === 'pdf')
|
|
81
83
|
return 'pdf'
|
|
82
|
-
if (ext === 'docx'
|
|
84
|
+
if (ext === 'docx')
|
|
83
85
|
return 'docx'
|
|
84
|
-
if (ext === '
|
|
86
|
+
if (ext === 'doc')
|
|
87
|
+
return 'doc'
|
|
88
|
+
if (ext === 'xlsx')
|
|
85
89
|
return 'xlsx'
|
|
86
|
-
if (ext === '
|
|
90
|
+
if (ext === 'xls')
|
|
91
|
+
return 'xls'
|
|
92
|
+
if (['txt', 'md', 'log', 'csv', 'json', 'xml', 'yaml', 'yml', 'ini', 'conf', 'properties'].includes(ext))
|
|
87
93
|
return 'text'
|
|
88
94
|
return 'unsupported'
|
|
89
95
|
}
|
|
@@ -63,7 +63,8 @@ const photoSignatureComponentMap = {
|
|
|
63
63
|
photoSignature,
|
|
64
64
|
qinHuaSignature: QinHuaSignature,
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
// 水印配置
|
|
67
|
+
const blurThreshold = ref<number>(30)
|
|
67
68
|
// 操作人信息
|
|
68
69
|
const checkerInfo = useUserStore().getUserInfo()
|
|
69
70
|
const safecheckStore = useSafecheckStore()
|
|
@@ -502,7 +503,11 @@ onBeforeMount(() => {
|
|
|
502
503
|
|
|
503
504
|
// 统一转交到 continuePageInit 决定是否弹窗
|
|
504
505
|
continuePageInit()
|
|
505
|
-
|
|
506
|
+
getConfigByName('PhotoWatermarkConfig', (result) => {
|
|
507
|
+
if (result) {
|
|
508
|
+
blurThreshold.value = result?.blurThreshold || 30
|
|
509
|
+
}
|
|
510
|
+
}, 'af-safecheck')
|
|
506
511
|
// 获取对应aiKeyToFieldMap
|
|
507
512
|
getConfigByName('AICheckConfig', (res: any) => {
|
|
508
513
|
aiKeyToFieldMap.value = res?.aiKeyToFieldMap || {
|
|
@@ -2824,6 +2829,7 @@ provide('provideParent', {
|
|
|
2824
2829
|
:is-view-mode="isReadOnly"
|
|
2825
2830
|
:extra-data="row?.extraData || {}"
|
|
2826
2831
|
:ai-synced-info-map="syncedItemInfoMap"
|
|
2832
|
+
:blur-threshold="blurThreshold"
|
|
2827
2833
|
@value-change="(selVal, selObj, currentVal, payload) => { valueChange(currentVal, pIndex, payload) }"
|
|
2828
2834
|
@device-deleted="cleanupDeletedDeviceData"
|
|
2829
2835
|
@success-file-list="successFileList"
|
|
@@ -24,6 +24,7 @@ const props = defineProps<{
|
|
|
24
24
|
maxCount: number // 该步骤允许的最大拍照数量
|
|
25
25
|
isLast: boolean // 是否为最后一个步骤
|
|
26
26
|
enableUpload?: boolean // 是否启用上传功能(true时点击拍照按钮先弹出选择)
|
|
27
|
+
blurThreshold?: number // 图片模糊度阈值
|
|
27
28
|
}>()
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -151,10 +152,14 @@ function triggerCamera() {
|
|
|
151
152
|
return
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
const param = {
|
|
156
|
+
blurThreshold: props.blurThreshold ?? 30,
|
|
157
|
+
}
|
|
158
|
+
console.warn('param', JSON.stringify(param))
|
|
154
159
|
// 调用Native方法打开相机
|
|
155
160
|
mobileUtil.execute({
|
|
156
161
|
funcName: 'takePicture',
|
|
157
|
-
param
|
|
162
|
+
param,
|
|
158
163
|
// 拍照成功后的回调函数
|
|
159
164
|
callbackFunc: (result: any) => {
|
|
160
165
|
// 检查返回状态是否成功
|
|
@@ -81,6 +81,10 @@ const props = defineProps({
|
|
|
81
81
|
type: Object,
|
|
82
82
|
default: () => ({}),
|
|
83
83
|
},
|
|
84
|
+
blurThreshold: {
|
|
85
|
+
type: Number,
|
|
86
|
+
default: 30,
|
|
87
|
+
},
|
|
84
88
|
})
|
|
85
89
|
|
|
86
90
|
/**
|
|
@@ -126,6 +130,7 @@ const photoAiRecognitionConfig = ref<any>(null)
|
|
|
126
130
|
/** 从父组件传入的已同步属性信息映射,透传给PhotoRecognitionInfo用于标记哪些属性已同步并可点击跳转 */
|
|
127
131
|
const syncedItemInfoMap = computed(() => props.aiSyncedInfoMap)
|
|
128
132
|
|
|
133
|
+
const blurThreshold = computed(() => props.blurThreshold)
|
|
129
134
|
// ========================================
|
|
130
135
|
// 计算属性
|
|
131
136
|
// ========================================
|
|
@@ -196,6 +201,7 @@ onMounted(() => {
|
|
|
196
201
|
*/
|
|
197
202
|
function init() {
|
|
198
203
|
const fromConfig = props.extraData?.checkAiSlotFrom || 'photoAiRecognitionForm'
|
|
204
|
+
console.warn('props', JSON.stringify(props))
|
|
199
205
|
console.warn('fromConfig', fromConfig)
|
|
200
206
|
getConfigByName('CheckAiSlotFromDic', (res: any) => {
|
|
201
207
|
console.warn('CheckAiSlotFromDic', res)
|
|
@@ -765,6 +771,7 @@ defineExpose({
|
|
|
765
771
|
:max-count="Number(step.acceptCount ?? 0)"
|
|
766
772
|
:is-last="step.model === stepColumns[stepColumns.length - 1]?.model"
|
|
767
773
|
:enable-upload="step.enableUpload"
|
|
774
|
+
:blur-threshold="blurThreshold"
|
|
768
775
|
@capture="(file) => handleCaptureSuccess(step, file)"
|
|
769
776
|
@next="handleNextStep"
|
|
770
777
|
@prev="handlePrevStep"
|
|
@@ -18,6 +18,7 @@ interface WatermarkConfig {
|
|
|
18
18
|
alpha?: number
|
|
19
19
|
userName?: string
|
|
20
20
|
enableRePhotoCheck?: boolean
|
|
21
|
+
blurThreshold?: number | string
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const props = defineProps({
|
|
@@ -178,6 +179,8 @@ function triggerCamera() {
|
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
|
|
182
|
+
param.blurThreshold = props.attr?.watermark?.blurThreshold ?? 30
|
|
183
|
+
|
|
181
184
|
mobileUtil.execute({
|
|
182
185
|
funcName: 'takePicture',
|
|
183
186
|
param,
|