源文件

This commit is contained in:
gyq
2024-05-23 14:39:33 +08:00
commit a1128dd791
2997 changed files with 500069 additions and 0 deletions

View File

@@ -0,0 +1,426 @@
<template>
<view>
<view class="default">
<!-- 删除按钮 -->
<view class="clear" v-if="vdata.hasImg && isShowClear && userIsShowClear">
<!-- -->
<image src="../../static/img/close.svg" @click.stop="logoutPopup.open()" mode="aspectFill"></image>
<!-- <image src="../../static/img/clear.svg" @click.stop="logoutPopup.open()"></image> -->
</view>
<view @click="previewImg" class="img-bg" v-if="vdata.hasImg">
<image :src="vdata.assemblyUrl" class="img-suc" mode="aspectFill"></image>
</view>
<image
v-if="!vdata.hasImg"
class="camera"
@click="chooseImg(['album', 'camera'])"
src="/static/iconImg/upload-picture.svg"
></image>
</view>
<!-- 图片预览手写非原生 -->
<enlarge
v-if="isPreview"
:changeIsShow="props.isShowClear"
:imgs="vdata.assemblyUrl"
@enlargeClose="enlargeClose"
@chooseImg="chooseImg"
/>
<!-- 删除图片二次确认 -->
<uni-popup ref="logoutPopup" type="dialog">
<uni-popup-dialog mode="base" :before-close="true" @close="logoutPopup.close()" @confirm="clear">
<template #title>
<view class="tip-content">确定要删除该图片吗</view>
</template>
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import appConfig from "@/config/appConfig.js"
import { ref, reactive, watch, onMounted, nextTick } from "vue"
import { $ossFilesForm, $imgInfoDetail } from "@/http/apiManager.js"
import storageManage from "@/util/storageManage.js"
import enlarge from "./enlarge.vue" // 图片预览
import useBackPress from "@/hooks/useBackPress.js" // 返回阻断函数
import { sm4DecryptByResData } from "@/util/encryptUtil.js"
const logoutPopup = ref(null) // 二次确认弹框
const props = defineProps({
upLoadUrl: { type: String, default: "/api/ossFiles/singleFile" }, // 默认图片
imgUrl: { type: String, default: "" }, // 默认图片
recogObjectType: { type: String, default: "" }, // 识别对象类型idcard, idcard_back, bankcard, business_license
uploadCount: { type: Number, default: 1 }, // 上传图片张数
size: { type: Number, default: 2 }, // 图片限制大小,单位M
imgTypes: { type: Array, default: () => ["jpg", "jpeg", "png"] }, // 图片类型限制,如: ['jpg', 'jpeg']
isShowClear: { type: Boolean, default: true }, // 进件成功不展示删除按钮与更换按钮
ocrFlag: { type: String, default: "" }, // ocr识别标志图片类型 idCard-身份证bankCard-银行卡, license-营业执照
userIsShowClear: { type: Boolean, default: true }, // 在其余页面中是否展示删除按钮
})
onMounted(() => {
if (props.imgUrl) {
vdata.hasImg = true
vdata.assemblyUrl = props.imgUrl
}
})
// 关闭图片预览
const enlargeClose = () => {
isPreview.value = false
// #ifdef H5 || APP-PLUS
inactive()
// #endif
}
const vdata = reactive({
hasImg: false,
assemblyUrl: "",
})
watch(
() => props.imgUrl,
(newVal, oldVal) => {
nextTick(() => {
newVal ? (vdata.hasImg = true) : (vdata.hasImg = false)
vdata.assemblyUrl = newVal
})
}
)
const emit = defineEmits(["uploadSuccess", "clear"])
// OCR识别函数
function imgInfoDetail(res) {
$imgInfoDetail({
imgUrl: res.data,
type: props.ocrFlag,
}).then(({ bizData }) => {
if (Object.keys(bizData).length < 1) {
// uni.showToast({
// title: '图片识别失败',
// icon: 'none'
// })
} else {
uni.showToast({
title: "图片识别成功,已自动回填内容,请检查核对",
icon: "none",
})
}
res.ocrInfo = bizData
return emit("uploadSuccess", res)
})
}
function chooseImg(index) {
console.log(index)
if (props.isShowClear) {
uni.chooseImage({
count: props.uploadCount,
sizeType: ["compressed"],
sourceType: index,
crop: { quality: 20 },
success: (chooseImageRes) => {
isPreview.value = false //关闭图片预览
const msg = beforeUpload(chooseImageRes)
if (msg != "success") return uni.showToast({ title: msg, icon: "none" })
// 根据form信息判断图片上传地址
// 此处额外验证上传的图片是否含有name属性如果没有则用path代替
let sourceFileName
if (chooseImageRes.tempFiles[0].name) {
sourceFileName = chooseImageRes.tempFiles[0].name
} else {
sourceFileName = chooseImageRes.tempFiles[0].path
}
$ossFilesForm({
bizType: "applyment",
sourceFileName: sourceFileName,
sourceFileSize: chooseImageRes.tempFiles[0].size,
}).then(({ bizData }) => {
let url,
isOss,
ossImgUrl = ""
if (bizData.formActionUrl === "LOCAL_SINGLE_FILE_URL") {
url = appConfig.env.JEEPAY_BASE_URL + props.upLoadUrl
isOss = false
} else {
url = bizData.formActionUrl
ossImgUrl = { data: bizData.ossFileUrl }
isOss = true
}
// 调用图片上传方法
uploadImg(chooseImageRes.tempFilePaths, url, bizData.formParams, isOss, ossImgUrl)
console.log(url,'bizData.formParamsbizData.formParamsbizData.formParams');
})
},
})
}
}
// 上传图片
function uploadImg(tempFilePaths, url, formParams, isOss, ossImgUrl) {
const token = storageManage.token()
var successCount = 0 //多图时,上传成功数量
var qualification = [] //多图存储
uni.showLoading({ title: "上传中..." })
//循环上传图片
tempFilePaths.forEach((tempFilePath) => {
console.log(tempFilePath);
uni.uploadFile({
url: url,
filePath: tempFilePath,
name: "file",
header: {
itoken: token,
},
formData: formParams,
// 代表完成的函数 注:此处可以传入三个函数 success (成功)/ fail失败 / complete (完成)
complete(res) {
uni.hideLoading()
// oss接口特有情况
if (isOss) {
if (res.statusCode != 200) {
return uni.showToast({ title: "请求失败,请重试", icon: "none" })
}
// 如果存在OCR 识别信息那么要调用ocr识别函数
if (props.ocrFlag) return imgInfoDetail(ossImgUrl)
emit("uploadSuccess", ossImgUrl)
return (vdata.hasImg = true)
}
// res 即接口返回数据包
let {
statusCode, // 状态码
data, // 数据
msg, // 信息
errMsg, // 错误信息
} = res
// 接收请求,执行响应操作
if (statusCode != 200) {
uni.showToast({
title: "请求失败请重试statusCode" + statusCode,
icon: "none",
mask: true,
duration: 2000,
})
return
}
if (typeof data == "string") {
data = JSON.parse(data)
}
// 图片上传解密
if (data.encryptData) {
data.data = sm4DecryptByResData(data.encryptData)
}
//状态码为1001(未登录)
if (data.code == 1001) {
uni.showToast({
title: "请登录",
icon: "none",
mask: true,
duration: 1500,
})
setTimeout(function () {
uni.reLaunch({
url: "/pages/login/login",
})
}, 1500)
return
}
if (data.code != 0) {
uni.showToast({
title: data.msg || "请求失败,请重试",
duration: 2000,
mask: true,
icon: "none",
})
return
}
// 如果存在OCR 识别信息那么要调用ocr识别函数
if (props.ocrFlag) return imgInfoDetail(data)
// 没有遇到以上的情况
emit("uploadSuccess", data)
vdata.hasImg = true
},
})
})
}
// 上传图片前的校验
function beforeUpload(chooseImageRes) {
const tempFiles = chooseImageRes.tempFiles
let msg = "success"
if (tempFiles) {
for (let i = 0; i < tempFiles.length; i++) {
// 图片地址
let tempUrl = tempFiles[i].name || tempFiles[i].path
if (!tempUrl) {
msg = "请选择图片"
return msg
}
// 校验图片大小
if (tempFiles[i].size > props.size * 1024 * 1024) {
msg = "单张图片请不超过" + props.size + "MB"
return msg
}
// 校验后缀
if (!checkSuffix(tempUrl)) {
msg = "仅支持【" + props.imgTypes + "】格式的图片"
return msg
}
}
} else {
msg = "请选择图片"
return msg
}
if (chooseImageRes.tempFilePaths.length > props.uploadCount) {
msg = "最多上传" + props.uploadCount + "张图片"
return msg
}
return msg
}
// 校验图片后缀
function checkSuffix(fileName) {
const suffix = getFileSuffix(fileName).toLowerCase()
if (props.imgTypes.includes(suffix)) {
return true
}
return false
}
// 获取图片后缀
function getFileSuffix(fileName) {
if (!fileName || fileName.indexOf(".") < 0 || fileName.length <= 1) {
return ""
}
return fileName.substring(fileName.lastIndexOf(".") + 1)
}
let isPreview = ref(false) // 图片预览是否展示
// 预览图片
function previewImg() {
isPreview.value = true
// #ifdef H5 || APP-PLUS
active()
// #endif
// onceVar.imgView(true)
// let urls = [];
// urls.push(props.imgUrl)
// uni.previewImage({
// urls: urls
// });
}
// 叉号 清除图片
function clear() {
vdata.hasImg = false
emit("clear")
logoutPopup.value.close()
}
// #ifdef H5 || APP-PLUS
const { active, inactive } = useBackPress(enlargeClose) // onBackPress 阻断返回
// #endif
</script>
<style scoped lang="scss">
// 图片预览
.preview-img {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #000;
z-index: 25;
}
.camera {
width: 50rpx;
height: 50rpx;
}
.default {
position: relative;
width: 120rpx;
height: 120rpx;
background-color: #fff;
border-radius: 5rpx;
display: flex;
align-items: center;
justify-content: center;
border: 1rpx dashed #cccdd9;
}
.img-bg {
position: relative;
width: 120rpx;
height: 120rpx;
background: #f1f1f1;
border-radius: 12rpx;
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
/* margin-right: 30rpx; */
image {
height: 100%;
width: 100%;
}
}
.img-def {
width: 43rpx;
height: 37rpx;
}
.img-suc {
width: 100%;
/* height: 180rpx; */
border-radius: 12rpx;
}
.clear {
position: absolute;
top: -10rpx;
left: 90rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
z-index: 12;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
image {
width: 30rpx;
height: 30rpx;
}
}
.tip-content {
display: flex;
justify-content: center;
align-items: center;
height: 120rpx;
font-size: 32rpx;
font-weight: 700;
color: #3981ff;
}
</style>