| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <template>
- <popup :show="show" round :close-on-click-overlay="false" class="upload-progress-popup"
- @update:show="emit('update:show', $event)">
- <slot name="header"></slot>
- <div class="upload-box" v-loading="loading" element-loading-:text="t('上传中...')">
- <div class="box-header">
- <div class="upload-title">
- <span>{{ t('上传照片') }}</span>
- <span v-if="!uploadRequired" class="optional">{{ t('(可选)') }}</span>
- </div>
- <div class="ai-btn">{{ t('AI 智能分析') }}</div>
- </div>
- <upload ref="uploadRef" :maxCount="10" :initImgArr="displayImgArr" :before-read="beforeReadUpload"
- :after-read="afterReadUpload">
- </upload>
- <!-- <div class="upload-result">{{ t('AI识别结果:该病为该病为该病为该病为病为该病为病为该病为') }}</div> -->
- </div>
- <slot name="footer"></slot>
- <div class="upload-action-btns">
- <div class="cancel-btn" @click="emit('cancel')">{{ t('取消') }}</div>
- <div class="confirm-btn" @click="handleConfirm">{{ confirmText }}</div>
- </div>
- </popup>
- </template>
- <script setup>
- import { useI18n } from "@/i18n";
- const { t } = useI18n();
- import { ref, computed, watch } from 'vue';
- import { Popup } from 'vant';
- import { ElMessage } from 'element-plus';
- import upload from '@/components/upload.vue';
- import UploadFile from "@/utils/upliadFile";
- import { getFileExt } from "@/utils/util";
- import {base_img_url2} from '@/api/config';
- const props = defineProps({
- show: {
- type: Boolean,
- default: false,
- },
- popupImageUploadLoading: {
- type: Boolean,
- default: false,
- },
- initImgArr: {
- type: Array,
- default: () => [],
- },
- confirmText: {
- type: String,
- default: '确认信息',
- },
- /** 是否必传图片,默认必传 */
- uploadRequired: {
- type: Boolean,
- default: true,
- },
- });
- const emit = defineEmits(['update:show', 'cancel', 'confirm', 'reset']);
- const uploadRef = ref(null);
- const popupInnerImgArr = ref([]);
- const popupInnerLoading = ref(false);
- const uploadFileObj = new UploadFile();
- const miniUserId = localStorage.getItem("MINI_USER_ID");
- const loading = computed(() => props.popupImageUploadLoading || popupInnerLoading.value);
- /** 弹窗内上传优先展示,否则回显父组件传入的 initImgArr */
- const displayImgArr = computed(() =>
- popupInnerImgArr.value.length ? popupInnerImgArr.value : props.initImgArr,
- );
- function getConfirmImgArr() {
- if (popupInnerImgArr.value.length) {
- return [...popupInnerImgArr.value.map(item => base_img_url2 + item)];
- }
- return [...(props.initImgArr || [])];
- }
- const beforeReadUpload = () => {
- popupInnerLoading.value = false;
- return true;
- };
- const afterReadUpload = async (data) => {
- if (!Array.isArray(data)) {
- data = [data];
- }
- popupInnerLoading.value = true;
- try {
- for (const file of data) {
- const fileVal = file.file;
- file.status = "uploading";
- file.message = "上传中...";
- const ext = getFileExt(fileVal.name);
- const key = `birdseye-look-mini/${miniUserId}/${new Date().getTime()}.${ext}`;
- const resFilename = await uploadFileObj.put(key, fileVal);
- if (resFilename) {
- file.status = "done";
- file.message = "";
- popupInnerImgArr.value.push(resFilename);
- } else {
- file.status = "failed";
- file.message = "上传失败";
- ElMessage.error("图片上传失败,请稍后再试!");
- }
- }
- } finally {
- popupInnerLoading.value = false;
- }
- };
- function handleConfirm() {
- const imgArr = getConfirmImgArr();
- if (props.uploadRequired && !imgArr.length) {
- ElMessage.warning(t('请先上传照片'));
- return;
- }
- emit('confirm', imgArr);
- }
- function uploadReset() {
- popupInnerImgArr.value = [];
- popupInnerLoading.value = false;
- uploadRef.value?.uploadReset?.();
- }
- watch(
- () => props.show,
- (val) => {
- if (val) {
- uploadReset();
- emit('reset');
- }
- },
- );
- defineExpose({
- uploadReset,
- });
- </script>
- <style scoped lang="scss">
- .upload-progress-popup {
- width: 100%;
- padding: 24px 16px;
- background: linear-gradient(360deg, #FFFFFF 74.2%, #D1EBFF 100%);
- .upload-box {
- margin-bottom: 12px;
- position: relative;
- min-height: 88px;
- .box-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 12px;
- .upload-title {
- font-size: 16px;
- .optional {
- font-size: 12px;
- color: rgba(18, 18, 18, 0.2);
- }
- }
- .ai-btn {
- padding: 5px 10px;
- border-radius: 4px;
- background: rgba(33, 153, 248, 0.1);
- color: #2199F8;
- border: 1px solid #2199F8;
- opacity: 0.5;
- }
- }
- .upload-result {
- color: #646464;
- padding: 6px 10px;
- background: rgba(161, 161, 161, 0.1);
- border-radius: 5px;
- margin-top: 12px;
- }
- }
- .upload-action-btns {
- display: flex;
- gap: 10px;
- margin-top: 16px;
- .cancel-btn,
- .confirm-btn {
- flex: 1;
- border-radius: 4px;
- padding: 8px;
- text-align: center;
- font-size: 16px;
- }
- .cancel-btn {
- border: 1px solid #dcdfe6;
- color: #606266;
- background: #ffffff;
- }
- .confirm-btn {
- background: #2199f8;
- color: #ffffff;
- }
- }
- }
- </style>
|