123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- <template>
- <div class="img-list" v-viewer>
- <div class="img-item" v-for="(it,key) in imageList" :key="key">
- <div v-if="it.blobUrl" style="height: 100%;">
- <img :src="it.blobUrl"/>
- <ion-icon v-if="!readonly" :icon="closeCircleOutline" color="danger" class="remove-icon"
- @click="deleteFile(it)"></ion-icon>
- </div>
- </div>
- <div class="img-item" v-if="(!isSingle || imageList.length==0) && !readonly">
- <ion-button color="light" @click="takePicture()">
- <ion-icon :icon="addOutline" size="large"></ion-icon>
- </ion-button>
- </div>
- <ion-item v-if="readonly && imageList.length==0">
- <ion-label style="flex: 0 0 100% !important;"><p>暂无</p></ion-label>
- </ion-item>
- </div>
- </template>
- <script lang="ts">
- import {defineComponent, ref} from "vue";
- import {camera, cameraOutline, addOutline, closeCircleOutline} from "ionicons/icons";
- import {alertController, IonIcon, IonThumbnail, loadingController} from '@ionic/vue';
- import {Camera, CameraResultType, CameraSource} from '@capacitor/camera';
- import {deleteFile as deleteFileApi, getFileBase64, getList, uploadBase64} from '@/api/system/file';
- import {presentAlert} from "@/api/common";
- import {dealImage, base64ToBlob} from "@/utils/imageUtils";
- export default defineComponent({
- name: 'b-image',
- components: {IonIcon},
- props: {
- fileRefId: {type: String, default: ''},
- fileType: {type: Number, default: 1},
- readonly: {type: Boolean, default: true},
- isSingle: {type: Boolean, default: false} //只能上次一张图片
- },
- setup(props) {
- const accept = 'png,jpeg,jpg,gif';
- const imageList = ref<any>([]);
- const getImageList = () => {
- imageList.value = [];
- if (props.fileRefId)
- getList({fileRefID: props.fileRefId}).then(resultList => {
- imageList.value = resultList as any;
- imageList.value.forEach((img: any) => {
- if (!img.base64) {
- getFileBase64(img.fileId).then(base64Str => {
- if (base64Str)
- img.blobUrl = URL.createObjectURL(base64ToBlob("data:image/png;base64," + base64Str));
- });
- }
- });
- });
- };
- const takePicture = async () => {
- if (props.fileRefId === '' || props.fileRefId == null) {
- await presentAlert("参数fileRefId为空");
- return false;
- }
- const image = await Camera.getPhoto({
- quality: 90,
- allowEditing: true,
- source: CameraSource.Photos,
- resultType: CameraResultType.Uri,
- });
- if (!accept?.split(',').includes(image.format)) {
- await presentAlert("只能上传格式为:" + accept + "的文件");
- return null;
- }
- dealImage(image.webPath as string, 1000, saveFile);
- };
- const saveFile = async (newBase64: string) => {
- const formData = new FormData();
- formData.append('base64Str', newBase64 as any);
- formData.append("fileRefId", props.fileRefId);
- formData.append("fileType", props.fileType.toString());
- formData.append("isSingle", props.isSingle ? "1" : "0");
- const loading = await loadingController.create({
- cssClass: 'my-custom-class',
- message: '正在上传,请稍等...',
- duration: 2000,
- });
- await loading.present();
- uploadBase64(formData).then((result) => {
- if (result) {
- presentAlert("上传成功");
- /*getImageList();*/
- getList({fileRefID: props.fileRefId}).then(resultList => {
- const imgList = resultList as any;
- imgList.forEach((img: any) => {
- if (imageList.value.filter((it: any) => it.fileId === img.fileId).length == 0) {
- getFileBase64(img.fileId).then(base64Str => {
- if (base64Str) {
- img.blobUrl = URL.createObjectURL(base64ToBlob("data:image/png;base64," + base64Str));
- imageList.value.push(img);
- }
- });
- }
- });
- });
- }
- })
- };
- const deleteFile = async (item: any) => {
- const alert = await alertController.create({
- header: '提示!',
- message: '是否确认删除?',
- buttons: [
- {
- text: '取消',
- role: 'cancel'
- },
- {
- text: '确认删除',
- handler: async () => {
- const loading = await loadingController.create({
- cssClass: 'my-custom-class',
- message: '正在删除,请稍等...',
- duration: 2000,
- });
- await loading.present();
- deleteFileApi({fileId: item.fileId}).then(result => {
- if (result) {
- imageList.value = imageList.value.filter((it: any) => it.fileId != item.fileId);
- }
- });
- }
- }
- ],
- });
- await alert.present();
- }
- getImageList();
- return {
- camera,
- IonThumbnail,
- takePicture,
- imageList,
- deleteFile,
- addOutline,
- closeCircleOutline
- }
- }
- }
- );
- </script>
- <style lang="less">
- .img-list {
- display: flex;
- text-align: center;
- flex-direction: row;
- flex-wrap: wrap;
- padding: 5px 10px;
- .img-item {
- width: 25%;
- position: relative;
- padding: 0 5px;
- height: 80px;
- img {
- height: 100%;
- object-fit: cover;
- border-radius: 10px;
- width: 100%;
- }
- .remove-icon {
- position: absolute;
- right: -3px;
- top: -6px;
- font-size: 20px;
- }
- ion-button {
- --box-shadow: 0px;
- height: 73px;
- width: 75px;
- }
- }
- }
- .showbigimg {
- z-index: 10;
- width: 100%;
- height: 100%;
- background: #e1e1e1;
- display: flex;
- justify-content: center; /*在主轴上的对齐*/
- align-items: center; /*在交叉轴上中心点的对齐*/
- img {
- opacity: 1;
- vertical-align: middle;
- }
- }
- </style>
|