shangfutong-ui/jeepay-ui-uapp-agent/components/JeepayUpLoad/JeepayUpLoad.vue

427 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>