|
|
@@ -0,0 +1,339 @@
|
|
|
+<template>
|
|
|
+ <div class="w-8/12 h-5/6 p-2 rounded flex flex-col justify-center border bg-white">
|
|
|
+ <div class="p-header mx-1.5 h-16 text-2xl flex border-b">
|
|
|
+<!-- 刷新按钮-->
|
|
|
+ <a-button class="ant-icon-btn" type="primary" icon="reload" :loading="loadingState === 0" @click="loadImage" ></a-button>
|
|
|
+
|
|
|
+ <a-button class="ml-2" :type="tabKey===1?'primary':''" @click="callback(1)">选择图片</a-button>
|
|
|
+ <a-button class="ml-1" :type="tabKey===2?'primary':''" @click="callback(2)">上传图片</a-button>
|
|
|
+ </div>
|
|
|
+ <div class="p-con w-full px-1">
|
|
|
+
|
|
|
+ <loading v-if="tabKey===1" class="w-full h-full " :loading-state="loadingState" tip="获取图片中">
|
|
|
+ <div class="img-viewBox" :style="imgBoxStyle" ref="imgViewBox">
|
|
|
+ <div
|
|
|
+ v-for="item in images"
|
|
|
+ :key="item.path"
|
|
|
+ :class="`img-viewItem ${item.filePath === imgUrl?'img-viewItem-select bg-red-300':'bg-gray-400'}`"
|
|
|
+ :style="imgItemStyle"
|
|
|
+ @click="selectImg(item)"
|
|
|
+ >
|
|
|
+ <img class="w-auto h-full" :src="item.filePath" alt="item.fileName">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <template v-slot:loadFail>
|
|
|
+ <div class="w-full h-full flex justify-center items-center flex-col" >
|
|
|
+ <h2 class="text-2xl text-red-700">{{loadingMessage}}</h2>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </loading>
|
|
|
+
|
|
|
+<!-- 文件上传部分 -->
|
|
|
+ <div
|
|
|
+ v-if="tabKey===2"
|
|
|
+ class="w-full h-full flex flex-col">
|
|
|
+ <div class="w-full h-32 rounded
|
|
|
+ border overflow-hidden flex-shrink">
|
|
|
+ <upload-file
|
|
|
+ :type="1"
|
|
|
+ :multiple="true"
|
|
|
+ @change="uploadChangeHandle"
|
|
|
+ > </upload-file>
|
|
|
+ </div>
|
|
|
+ <div class="w-full h-full overflow-auto">
|
|
|
+ <div
|
|
|
+ v-for="file in fileList"
|
|
|
+ class="w-full h-64 rounded mt-2
|
|
|
+ border flex relative px-2">
|
|
|
+ <div class="w-full absolute bottom-0 left-0"
|
|
|
+ v-if="file.status !== fileState.waiting">
|
|
|
+ <a-progress :show-info="file.showInfo" :percent="file.percent" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="w-1/3 h-full p-4 relative rounded overflow-hidden">
|
|
|
+ <image-viewer :src="file.url"/>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="w-2/3 h-full flex items-center relative justify-between">
|
|
|
+ <div>
|
|
|
+<!-- 状态提示 -->
|
|
|
+ <div class="w-full">
|
|
|
+ <a-alert :message="file.showInfo_message"
|
|
|
+ :type="file.showInfo_type"
|
|
|
+ show-icon />
|
|
|
+ </div>
|
|
|
+ <span>
|
|
|
+ {{file.name}}
|
|
|
+ </span>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <a-button-group>
|
|
|
+ <a-button :disabled="file.status === fileState.uploading || file.status === fileState.success"
|
|
|
+ :loading="file.status === fileState.uploading" >删除</a-button>
|
|
|
+ <a-button :disabled="file.status === fileState.uploading || file.status === fileState.success"
|
|
|
+ :loading="file.status === fileState.uploading"
|
|
|
+ class="ml-2" @click="uploadFileItem(file)">上传</a-button>
|
|
|
+ </a-button-group>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="p-header w-full mt-2">
|
|
|
+ <a-button @click="close" type="danger">X</a-button>
|
|
|
+ <a-button class="ml-2" type="primary" @click="selectNowImg" :disabled="!imgUrl">选择当前照片</a-button>
|
|
|
+<!-- 移除选择的照片 -->
|
|
|
+ <a-button class="ml-2" v-show="imgUrl" type="danger" @click="removeFileHandle">移除选择的照片</a-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import handle from "~/until/handle";
|
|
|
+import Loading from "~/components/public/loading";
|
|
|
+import {db_base} from "../../map/dbField_esm";
|
|
|
+import {rCode} from "../../map/rcodeMap_esm";
|
|
|
+import UploadFile from "./uploadFile.vue";
|
|
|
+import ImageViewer from "./imageViewer.vue";
|
|
|
+import domTool from "~/until/domTool";
|
|
|
+
|
|
|
+const fileState = {
|
|
|
+ waiting: 'waiting',
|
|
|
+ uploading: 'uploading',
|
|
|
+ success: 'success',
|
|
|
+ fail: 'fail'
|
|
|
+}
|
|
|
+export default {
|
|
|
+ name: "imageTable",
|
|
|
+ components: {ImageViewer, UploadFile, Loading},
|
|
|
+ props: {
|
|
|
+ imgHeight: {
|
|
|
+ type: Number,
|
|
|
+ default: 150
|
|
|
+ },
|
|
|
+ lineItem: {
|
|
|
+ type: Number,
|
|
|
+ default: 5
|
|
|
+ },
|
|
|
+ // 间隔,单位px
|
|
|
+ gap: {
|
|
|
+ type: Number,
|
|
|
+ default: 5
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data(){
|
|
|
+ return {
|
|
|
+ uploadUrl: `/api/base/fileUp?type=${db_base.fileType.image}`,
|
|
|
+ tabKey: 1,
|
|
|
+ imgUrl:'',
|
|
|
+ fileData: {},
|
|
|
+ loadingState: 0,
|
|
|
+ loadingMessage: '',
|
|
|
+ searchKey: '',
|
|
|
+ fileType: db_base.fileType.image,
|
|
|
+ fileState: fileState,
|
|
|
+ fileList: [],
|
|
|
+ images: [],
|
|
|
+ imgBoxStyle: '',
|
|
|
+ imgItemStyle: '',
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ // this.comStyle();
|
|
|
+ await this.loadImage();
|
|
|
+ // 监听resize
|
|
|
+ },
|
|
|
+ methods:{
|
|
|
+ close(){
|
|
|
+ this.$emit('cancel')
|
|
|
+ },
|
|
|
+ // 选择图片
|
|
|
+ selectNowImg(){
|
|
|
+ if(!this.imgUrl){
|
|
|
+ return this.$message.warn('请选择图片')
|
|
|
+ }
|
|
|
+ this.$emit('ok',this.fileData);
|
|
|
+ },
|
|
|
+ comStyle(){
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ let el_imgViewBox = this.$refs.imgViewBox;
|
|
|
+ let res = domTool.comDomStyle(el_imgViewBox,this.lineItem,this.gap);
|
|
|
+ if(res === -1){
|
|
|
+ return this.$message.error('计算样式失败,元素不存在');
|
|
|
+ }
|
|
|
+ let {boxPadding,itemStyle} = res;
|
|
|
+ this.imgBoxStyle = boxPadding;
|
|
|
+ this.imgItemStyle = itemStyle + `;height:${this.imgHeight}px`;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ async loadImage(){
|
|
|
+ this.loadingState = 0;
|
|
|
+ let url = '/api/base/files';
|
|
|
+ let params = {
|
|
|
+ type: this.fileType + 1,
|
|
|
+ key: this.searchKey
|
|
|
+ };
|
|
|
+ let [err,res] = await handle(this.$axios.get(url,{params}));
|
|
|
+ if(err){
|
|
|
+ this.loadingState = 2;
|
|
|
+ this.loadingMessage = '获取图片失败';
|
|
|
+ return console.log(err);
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK){
|
|
|
+ this.loadingState = 1;
|
|
|
+ this.comStyle();
|
|
|
+ this.images = result.data;
|
|
|
+ }else{
|
|
|
+ this.loadingState = 2;
|
|
|
+ this.loadingMessage = `获取图片失败${result.msg}`;
|
|
|
+ this.$message.error(result.msg);
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ async uploadChangeHandle(files){
|
|
|
+ console.log(files);
|
|
|
+ console.log(`files is ${files.length}`);
|
|
|
+ // 文件预览
|
|
|
+ for(let i = 0;i<files.length;i++){
|
|
|
+ let file = files[i];
|
|
|
+ let [err,fileUrl] = await handle(this.fileToPreview(file));
|
|
|
+ if(err){
|
|
|
+ this.$message.warn(`文件${file.name}预览失败`);
|
|
|
+ // 文件转换失败
|
|
|
+ return console.log(err);
|
|
|
+ }
|
|
|
+ this.fileList.push({
|
|
|
+ file: file,
|
|
|
+ uid: file.uid,
|
|
|
+ name: file.name,
|
|
|
+ status: fileState.waiting,
|
|
|
+ percent: 0,
|
|
|
+ showInfo: false,
|
|
|
+ showInfo_message: '点击按钮进行上传',
|
|
|
+ showInfo_type: 'info',
|
|
|
+ url: fileUrl
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fileToPreview(file){
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let reader = new FileReader();
|
|
|
+ reader.readAsDataURL(file);
|
|
|
+ reader.onload = function (e) {
|
|
|
+ resolve(e.target.result);
|
|
|
+ };
|
|
|
+ reader.onerror = function (e) {
|
|
|
+ reject(e);
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
+ callback(key) {
|
|
|
+ console.log(key);
|
|
|
+ this.tabKey = key;
|
|
|
+ },
|
|
|
+ // 选择图片
|
|
|
+ selectImg(fileData){
|
|
|
+ console.log(`selectImg ${fileData.filePath} fileId is ${fileData.fileId}`);
|
|
|
+ this.imgUrl = fileData.filePath;
|
|
|
+ this.fileData = fileData;
|
|
|
+ },
|
|
|
+ // 编辑图片信息
|
|
|
+ editImg(fileData){
|
|
|
+ console.log(`editImg ${fileData.filePath} fileId is ${fileData.fileId}`);
|
|
|
+ },
|
|
|
+ async uploadFileItem(file){
|
|
|
+ if(!file || !file.file || file.status === fileState.fail){
|
|
|
+ return this.$message.error('调用异常,已经阻止上传');
|
|
|
+ }
|
|
|
+ file.showInfo = true;
|
|
|
+ file.status = fileState.uploading;
|
|
|
+ file.percent = 0;
|
|
|
+ file.showInfo_message = '上传中';
|
|
|
+ file.showInfo_type = 'info';
|
|
|
+ let form = new FormData();
|
|
|
+ form.append('file',file.file);
|
|
|
+ let [err,res] = await handle(this.$axios.post(this.uploadUrl,form,{
|
|
|
+ onUploadProgress: (progressEvent) => {
|
|
|
+ file.percent = Math.round((progressEvent.loaded * 100) / progressEvent.total) || 0;
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ if(err){
|
|
|
+ file.status = fileState.fail;
|
|
|
+ file.showInfo_message = `上传失败,${err.message}`;
|
|
|
+ file.showInfo_type = 'error';
|
|
|
+ return console.log(err);
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK) {
|
|
|
+ file.status = fileState.success;
|
|
|
+ file.showInfo_message = `文件上传成功`;
|
|
|
+ file.showInfo_type = 'success';
|
|
|
+ this.$message.success('上传成功');
|
|
|
+ await this.loadImage();
|
|
|
+ }else{
|
|
|
+ file.status = fileState.fail;
|
|
|
+ file.showInfo_message = `上传失败,${err.message}`;
|
|
|
+ file.showInfo_type = 'error';
|
|
|
+ this.$message.error(result.msg);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async updateFileItem(updateData){
|
|
|
+
|
|
|
+ },
|
|
|
+ async removeFileHandle(){
|
|
|
+ let fileData = this.fileData;
|
|
|
+ if(!fileData || !fileData.fileId){
|
|
|
+ return this.$message.warn('暂未选择图片');
|
|
|
+ }
|
|
|
+ let [err,res] = await handle(this.$axios.delete(`/api/base/file/${fileData.fileId}`));
|
|
|
+ if(err){
|
|
|
+ this.$message.error('删除图像资源失败');
|
|
|
+ return console.log(err);
|
|
|
+ }
|
|
|
+ let result = res.data;
|
|
|
+ if(result.code === rCode.OK) {
|
|
|
+ this.$message.success('删除图像资源成功');
|
|
|
+ this.imgUrl = '';
|
|
|
+ this.fileData = {};
|
|
|
+ await this.loadImage();
|
|
|
+ }else{
|
|
|
+ this.$message.error(result.msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.p-header{
|
|
|
+ height:35px;
|
|
|
+}
|
|
|
+.p-con {
|
|
|
+ height: calc(100% - 80px);
|
|
|
+}
|
|
|
+.img-viewBox{
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ justify-content: flex-start;
|
|
|
+ overflow: auto;
|
|
|
+}
|
|
|
+.img-viewItem{
|
|
|
+ cursor: pointer;
|
|
|
+ flex-shrink: 0;
|
|
|
+ transition: all 0.5s;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+.img-viewItem-select{
|
|
|
+ border: 2px solid #01eef5;
|
|
|
+ box-shadow: 0 0 2px #fff;
|
|
|
+}
|
|
|
+</style>
|