vue3+vant-ui 上传头像,base64文件流上传及回显
1 <script setup> 2 import { onMounted, reactive } from "vue"; 3 import { useRouter } from "vue-router"; 4 import request from '@/utils/request'; 5 import {removeEmptyProps,generatehashcode} from '@/utils/common'; 6 import { v4 as uuidv4 } from 'uuid'; 7 const uuid = uuidv4(); 8 document.title = '申请员工证'; 9 10 const router = useRouter(); 11 let loading = $ref(false) 12 let statusType = $ref() 13 let userInfo = $ref({}); 14 let photoFile = $ref(''); 15 let upLoadPhoto = $ref(''); 16 const fileList = $ref([]); 17 const photos = $ref([]); 18 const files = $ref(); 19 const uploadfileData = $ref( 20 { 21 hashcode: [] // 文件生成的hashcode 22 } 23 ); 24 25 const onLoad = () => { 26 console.log('onLoad...') 27 getData(); 28 getBalanceOrOverdue() 29 } 30 31 const onRefresh = () => { 32 console.log('onRefresh...') 33 userInfo = {}; 34 getData(); 35 } 36 37 const queryParams = reactive({ 38 phone: sessionStorage.getItem('userPhone') || '', 39 }); 40 41 const goOrderDetail = (id) => { 42 router.push({ name: "myGroupDetail", query: { id: id, } }); 43 }; 44 45 onMounted(() => { 46 getData(); 47 48 }); 49 50 // 请求接口获取员工信息数据 51 const getData = async () => { 52 loading = true; 53 const params = removeEmptyProps(queryParams); 54 const { status, data, message} = await request.get('/api/oa/user/apply/card/getUserInfoByPhone', params, { 55 headers: { 56 Authorization: sessionStorage.getItem('myToken') 57 } 58 }); 59 if (status == 200) { 60 // 计算finished 61 // finished = rows.length < queryParams.limit; 62 // 合并数据 63 userInfo = data 64 //如果有照片id就获取照片,说明申请通过了 65 if (userInfo.photoId) { 66 // 如果员工证申请通过则清除缓存头像 67 localStorage.removeItem('photoFile') 68 getPhotoFile()//获取头像 69 }else{ 70 let localPhotoFile = localStorage.getItem('photoFile') 71 // 如果有缓存头像就显示缓存头像 72 if(localPhotoFile){ 73 photoFile = localPhotoFile 74 // console.log("缓存中获取photoFile:",photoFile); 75 } 76 } 77 } else { 78 // 获取数据失败提示 79 showToast(message); 80 sessionStorage.clear(); 81 router.push('/myGroup/loginCode'); 82 } 83 loading = false; 84 }; 85 86 // 获取员工头像 87 const getPhotoFile = async () => { 88 // const params = removeEmptyProps(userInfo); 89 const params = { 90 // photoFileId: userInfo.photoId 91 } 92 const res = await request.get('/api/admin/baseFile/showPic/'+ userInfo.photoId,params, { 93 headers: { 94 Authorization: sessionStorage.getItem('myToken') 95 } 96 }); 97 photoFile ='data:image/jpeg;base64,'+ res;//获取头像显示 98 console.log("imgurl:",imgurl,fileList); 99 }; 100 // 上传头像前处理 101 const beforeRead = (file) => { 102 console.log("上传头像前处理:",file); 103 if (file.type !== 'image/jpeg' && file.type !== 'image/jpg' && file.type !== 'image/png') { 104 showToast('请上传 jpg、jpeg、png 格式图片'); 105 return false; 106 } 107 return true; 108 }; 109 const afterRead = async (file) => { 110 console.log("上传file:",file,file.content); 111 //将file.content 放在缓存photoFile中 112 localStorage.setItem('photoFile', file.content) 113 uploadfileData.files = files 114 fileList.forEach(v=> { 115 let o = { 116 base64Str: v.content, 117 filename: v.file.name 118 } 119 photos.push(o) 120 }) 121 console.log("photos:",photos); 122 // 把file.content转成binary 123 const binary = await base64ImgtoFile(file.content, file.name) 124 uploadPhone(binary) 125 } 126 // 上传接口 127 const uploadPhone = async (file) => { 128 const params = removeEmptyProps(queryParams); 129 // const hashcode = await generatehashcode(file); 130 // 把uploadfileData包装成FormData 131 const formdata = new FormData(); 132 formdata.append('files', file); 133 formdata.append('hashcode', uuid) 134 135 const { result, fileNames,msg } = await request.post('/api/admin/baseFile/upload', formdata, { 136 headers: { 137 Authorization: sessionStorage.getItem('myToken'), 138 'Content-Type': 'multipart/form-data' 139 } 140 }); 141 if (result == 'success') { 142 upLoadPhoto = fileNames[0] 143 console.log("上传成功:",upLoadPhoto); 144 // 获取员工信息 145 getData(); 146 } else { 147 // 获取数据失败提示 148 showToast(msg); 149 } 150 loading = false; 151 }; 152 153 // base64转文件 154 const base64ImgtoFile = async (dataurl, filename = 'file') => { 155 const arr = dataurl.split(',') 156 const mime = arr[0].match(/:(.*?);/)[1] 157 const suffix = mime.split('/')[1] 158 const bstr = atob(arr[1]) 159 let n = bstr.length 160 const u8arr = new Uint8Array(n) 161 while (n--) { 162 u8arr[n] = bstr.charCodeAt(n) 163 } 164 return new File([u8arr], `${filename}.${suffix}`, { 165 type: mime 166 }) 167 } 168 // 申请员工证 169 const applyCard = async () => { 170 // if(userInfo.photoId == null || userInfo.photoId == '' || userInfo.photoId == undefined){ 171 if(userInfo.photoId == undefined){ 172 if(upLoadPhoto == '' ){ 173 showToast("请上传员工照片"); 174 return false; 175 } 176 } 177 178 const params = removeEmptyProps(userInfo); 179 const {status, message,rows} = await request.post('/api/oa/user/apply/card/add',params, { 180 headers: { 181 Authorization: sessionStorage.getItem('myToken') 182 } 183 }); 184 if (status == 400) { 185 // 处理完成后赋值给regionOptions 186 showToast("申请成功"); 187 statusType = true 188 getData() 189 } else { 190 // 申请失败提示 191 showToast(message); 192 } 193 }; 194 195 196 </script> 197 198 <template> 199 <van-nav-bar left-arrow left-text="返回" @click-left="router.back()" title="申请员工证" fixed :border="false"></van-nav-bar> 200 <div class="top-data-group"> 201 <div class="top-data-group__top" @click="goOrderDetail(1)"> 202 {{ userInfo.orgName }} 203 </div> 204 <div style="display: flex; justify-content: space-around;"> 205 206 <!-- <van-image 207 v-if="userInfo.photoId !=null && userInfo.photoId != '' && userInfo.photoId != undefined" 208 width="100" 209 height="150" 210 :src="photoFile" 211 /> --> 212 <van-image 213 v-if="photoFile" 214 width="100" 215 height="150" 216 :src="photoFile" 217 /> 218 <van-uploader v-if="photoFile == null || photoFile == '' || photoFile == undefined" v-model="fileList" preview-size="100px" reupload="true" max-count="1" :after-read="afterRead" :before-read="beforeRead"/> 219 </div> 220 <van-row class="list-row"> 221 <van-col span="24"> 222 <van-row> 223 <van-col span="6">部 门:</van-col> 224 <van-col span="18">{{ userInfo.deptName }}</van-col> 225 </van-row> 226 </van-col> 227 <van-col span="24"> 228 <van-row> 229 <van-col span="6">职 位:</van-col> 230 <van-col span="18">{{ userInfo.jobName }}</van-col> 231 </van-row> 232 </van-col> 233 <van-col span="24"> 234 <van-row> 235 <van-col span="6">员工名称:</van-col> 236 <van-col span="18">{{ userInfo.userName }}</van-col> 237 </van-row> 238 </van-col> 239 <van-col span="24"> 240 <van-row> 241 <van-col span="6">办 公 地:</van-col> 242 <van-col span="18">{{ userInfo.workspace }}</van-col> 243 </van-row> 244 </van-col> 245 <van-col span="24"> 246 <van-row> 247 <van-col span="6">工 号:</van-col> 248 <van-col span="18">{{ userInfo.staffNo }}</van-col> 249 </van-row> 250 </van-col> 251 252 </van-row> 253 <div style="margin: 16px;"> 254 <van-button round block type="primary" :disabled="statusType == true || userInfo.status != undefined" v-if="userInfo.hasCard == false" @click="applyCard"> 255 <span v-if="userInfo.status == undefined">申请员工证</span> 256 <span v-if="userInfo.hasCard == false && userInfo.status == 0">待审核{{ statusType }}</span> 257 <span v-if="userInfo.hasCard == false && userInfo.status == 1">审核通过</span> 258 <span v-if="userInfo.hasCard == false && userInfo.status == 2">审核拒绝</span> 259 <span v-if="userInfo.hasCard == false && userInfo.status == 3">审核中</span> 260 261 </van-button> 262 <van-button round block disabled type="primary" v-if="userInfo.hasCard == true"> 263 已申请过了 264 </van-button> 265 </div> 266 </div> 267 </template> 268 269 <style scoped lang="scss"> 270 .top-data-group { 271 // 固定在顶部,距离顶部100px 272 position: fixed; 273 top: 50px; 274 left: 0; 275 right: 0; 276 .top-data-group__top { 277 // background-color: #1989fa; 278 padding: 10px 15px 15px 15px; 279 text-align: center; 280 font-size: 16px; 281 font-weight: bold; 282 } 283 } 284 285 286 .btn-group { 287 display: flex; 288 margin: 16px; 289 justify-content: center; 290 align-items: center; 291 } 292 .list-row{ 293 padding: 20px 20px; 294 //文字两端对齐 295 text-align: justify; 296 .van-col{ 297 margin-bottom: 2px; 298 } 299 } 300 .van-image{ 301 height: 120px!important; 302 } 303 .van-uploader__upload{ 304 height: 140px!important; 305 306 } 307 </style>