|
@@ -0,0 +1,128 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="image-upload">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="image-preview"
|
|
|
|
|
+ v-for="(url, index) in imageUrls"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-image
|
|
|
|
|
+ style="width: 100px; height: 100px"
|
|
|
|
|
+ :src="url"
|
|
|
|
|
+ :preview-src-list="imageUrls"
|
|
|
|
|
+ >
|
|
|
|
|
+ </el-image>
|
|
|
|
|
+ <div class="image-actions">
|
|
|
|
|
+ <el-button type="text" @click="handleRemove(index)" v-if="!disabled">删除</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ v-if="!limit || value.length < limit"
|
|
|
|
|
+ class="image-uploader"
|
|
|
|
|
+ action="#"
|
|
|
|
|
+ accept="image/png,image/jpeg,image/jpg"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ :http-request="handleUpload"
|
|
|
|
|
+ :disabled="disabled"
|
|
|
|
|
+ >
|
|
|
|
|
+ <i class="el-icon-plus image-uploader-icon"></i>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+ import { uploadFile } from '@/api/system/file/index';
|
|
|
|
|
+ import { getImagePath } from '@/utils/file';
|
|
|
|
|
+
|
|
|
|
|
+ export default {
|
|
|
|
|
+ props: {
|
|
|
|
|
+ value: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => []
|
|
|
|
|
+ },
|
|
|
|
|
+ module: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: 'main'
|
|
|
|
|
+ },
|
|
|
|
|
+ disabled: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
|
|
+ limit: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ default: 0
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ imageUrls() {
|
|
|
|
|
+ return (this.value || []).map((item) => {
|
|
|
|
|
+ const path = typeof item === 'string' ? item : item.url || '';
|
|
|
|
|
+ return path ? getImagePath(path) : '';
|
|
|
|
|
+ }).filter(Boolean);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ async handleUpload(params) {
|
|
|
|
|
+ const file = params.file;
|
|
|
|
|
+ if (!file.type.startsWith('image/')) {
|
|
|
|
|
+ this.$message.error('只能上传图片文件');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (file.size / 1024 / 1024 > 2) {
|
|
|
|
|
+ this.$message.error('图片大小不能超过 2MB');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await uploadFile({
|
|
|
|
|
+ module: this.module,
|
|
|
|
|
+ multiPartFile: file
|
|
|
|
|
+ });
|
|
|
|
|
+ if (res.data && res.data.storePath) {
|
|
|
|
|
+ const newList = [...this.value, res.data.storePath];
|
|
|
|
|
+ this.$emit('input', newList);
|
|
|
|
|
+ this.$message.success('上传成功');
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ this.$message.error('上传失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ handleRemove(index) {
|
|
|
|
|
+ const newList = [...this.value];
|
|
|
|
|
+ newList.splice(index, 1);
|
|
|
|
|
+ this.$emit('input', newList);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+ .image-upload {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .image-preview {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .image-actions {
|
|
|
|
|
+ margin-top: 5px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .image-uploader {
|
|
|
|
|
+ .image-uploader-icon {
|
|
|
|
|
+ font-size: 28px;
|
|
|
|
|
+ color: #8c939d;
|
|
|
|
|
+ width: 100px;
|
|
|
|
|
+ height: 100px;
|
|
|
|
|
+ line-height: 100px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ border: 1px dashed #d9d9d9;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ border-color: #409eff;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|