|
|
@@ -19,7 +19,7 @@
|
|
|
<a :style="file.status === 'error' ? 'color: red' : ''" @click="handlePreview(file)">{{ file.name }}</a>
|
|
|
<a-space style="margin-right: 10px">
|
|
|
<span style="color:#1677ff" v-show="file.originFileObj=='[object File]'">
|
|
|
- 上传进度:{{file.percent.toFixed(2)}}%
|
|
|
+ 上传进度:{{ file.percent.toFixed(2) }}%
|
|
|
</span>
|
|
|
<a style="font-size:16px;margin-right: 10px" href="javascript:;" @click="handlePreview(file)">
|
|
|
<EyeOutlined/>
|
|
|
@@ -37,21 +37,44 @@
|
|
|
</template>
|
|
|
</a-upload-dragger>
|
|
|
<!-- 预览弹框 -->
|
|
|
- <a-modal
|
|
|
- v-model:open="previewVisible"
|
|
|
- title="附件预览"
|
|
|
- :footer="null"
|
|
|
- :width="'100vw'"
|
|
|
- wrap-class-name="fullscreen-modal"
|
|
|
- :style="{ top: '0', left: '0' }"
|
|
|
- :bodyStyle="{
|
|
|
- height: 'calc(100vh - 95px)',
|
|
|
- padding: '0',
|
|
|
- overflow: 'auto',
|
|
|
- }"
|
|
|
+ <vue-draggable-resizable
|
|
|
+ v-show="previewVisible"
|
|
|
+ :x="x1"
|
|
|
+ :y="y1"
|
|
|
+ :w="width"
|
|
|
+ :h="height"
|
|
|
+ class="popup-resize"
|
|
|
+ :resizable="true"
|
|
|
+ :draggable="draggableResize"
|
|
|
+ @resizing="handleResizing"
|
|
|
+ @dragging="onDragging"
|
|
|
+ :active="previewActive"
|
|
|
+ :min-width="300"
|
|
|
+ :min-height="100"
|
|
|
>
|
|
|
- <iframe :src="previewUrl" width="100%" height="100%" frameborder="0"></iframe>
|
|
|
- </a-modal>
|
|
|
+ <div class="draggable-title">
|
|
|
+ <span class="preview-left">附件预览</span>
|
|
|
+ <span class="preview-title">{{ fileName }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="draggable-content">
|
|
|
+ <iframe v-show="iframeShow" :src="previewUrl" width="100%" height="100%" frameborder="0"></iframe>
|
|
|
+ <div v-show="!iframeShow" class="overlay">
|
|
|
+ <a-divider class="horizontal" dashed>宽: {{ width }}</a-divider>
|
|
|
+ <a-divider class="vertical" type="vertical" dashed>高: {{ height }}</a-divider>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="control-buttons">
|
|
|
+ <a-button v-show="!maxed" class="control-button" @click="maximize">
|
|
|
+ <ExpandOutlined/> <!-- 最大化图标 -->
|
|
|
+ </a-button>
|
|
|
+ <a-button v-show="maxed" class="control-button" @click="restore">
|
|
|
+ <ShrinkOutlined/> <!-- 返回图标 -->
|
|
|
+ </a-button>
|
|
|
+ <a-button class="control-button" @click="closeDrag">
|
|
|
+ <CloseOutlined/> <!-- 关闭图标 -->
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ </vue-draggable-resizable>
|
|
|
|
|
|
<a-drawer
|
|
|
title="附件预览"
|
|
|
@@ -81,11 +104,16 @@ import {useUserStore} from '/@/store/modules/system/user.js';
|
|
|
import dayjs from 'dayjs';
|
|
|
import {Base64} from 'js-base64';
|
|
|
import {message, Modal} from 'ant-design-vue';
|
|
|
+import VueDraggableResizable from 'vue-draggable-resizable'
|
|
|
+import "vue-draggable-resizable/style.css";
|
|
|
|
|
|
const fileUrl = import.meta.env.VITE_APP_API_FILE_VIEW_URL;
|
|
|
export default {
|
|
|
name: 'StUploadFile',
|
|
|
props: ['record', 'value', 'config', 'parentDisabled', 'dynamicData'],
|
|
|
+ components: {
|
|
|
+ VueDraggableResizable
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
fileList: [],
|
|
|
@@ -94,8 +122,31 @@ export default {
|
|
|
previewVisible: false, // 控制弹框显示
|
|
|
previewVisibleMobile: false,
|
|
|
previewUrl: '', // 预览的 URL
|
|
|
+ x1: 100,
|
|
|
+ y1: 10,
|
|
|
+ x2: 100,
|
|
|
+ y2: 10,
|
|
|
+ width: 0,
|
|
|
+ height: 0,
|
|
|
+ lastWidth: 0,
|
|
|
+ lastHeight: 0,
|
|
|
+ maxed: false,
|
|
|
+ scaleFactor: 1.1,
|
|
|
+ iframeShow: true,
|
|
|
+ previewActive: false,
|
|
|
+ fileName: '',
|
|
|
+ draggableResize: true,
|
|
|
};
|
|
|
},
|
|
|
+ mounted() {
|
|
|
+ this.width = window.innerWidth - 200
|
|
|
+ this.height = window.innerHeight - 90
|
|
|
+ document.addEventListener('mouseup', this.handleGlobalMouseUp);
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ // 在组件销毁时移除全局 mouseup 事件
|
|
|
+ document.removeEventListener('mouseup', this.handleGlobalMouseUp);
|
|
|
+ },
|
|
|
watch: {
|
|
|
value: {
|
|
|
// value 需要深度监听及默认先执行handler函数
|
|
|
@@ -132,6 +183,23 @@ export default {
|
|
|
this.fileList = this.value;
|
|
|
}
|
|
|
},
|
|
|
+ // 调整大小过程中持续触发
|
|
|
+ handleResizing(x, y, width, height) {
|
|
|
+ this.x1 = x
|
|
|
+ this.y1 = y
|
|
|
+ this.width = width
|
|
|
+ this.height = height
|
|
|
+ this.iframeShow = false
|
|
|
+ this.maxed = false
|
|
|
+ },
|
|
|
+ onDragging(x, y) {
|
|
|
+ this.x1 = x
|
|
|
+ this.y1 = y
|
|
|
+ this.maxed = false
|
|
|
+ },
|
|
|
+ handleGlobalMouseUp() {
|
|
|
+ this.iframeShow = true
|
|
|
+ },
|
|
|
handleSelectChange() {
|
|
|
setTimeout(() => {
|
|
|
this.$emit('update:value', this.fileList); //主表,直接更新value
|
|
|
@@ -159,7 +227,9 @@ export default {
|
|
|
this.previewVisibleMobile = true;
|
|
|
} else {
|
|
|
this.previewUrl = viewFile;
|
|
|
+ this.fileName = file.name
|
|
|
this.previewVisible = true; // 显示弹框
|
|
|
+ this.previewActive = true;
|
|
|
}
|
|
|
},
|
|
|
handleRemove(file) {
|
|
|
@@ -186,13 +256,33 @@ export default {
|
|
|
this.$message.error(`文件上传失败`);
|
|
|
}
|
|
|
},
|
|
|
+ closeDrag() {
|
|
|
+ this.previewVisible = false
|
|
|
+ },
|
|
|
+ maximize() {
|
|
|
+ this.maxed = true
|
|
|
+ this.lastWidth = this.width
|
|
|
+ this.lastHeight = this.height
|
|
|
+ this.x2 = this.x1
|
|
|
+ this.y2 = this.y1
|
|
|
+ this.width = window.innerWidth
|
|
|
+ this.height = window.innerHeight
|
|
|
+ this.x1 = 0
|
|
|
+ this.y1 = 0
|
|
|
+ this.draggableResize=false
|
|
|
+ },
|
|
|
+ restore() {
|
|
|
+ this.width = this.lastWidth
|
|
|
+ this.height = this.lastHeight
|
|
|
+ this.x1 = this.x2
|
|
|
+ this.y1 = this.y2
|
|
|
+ this.maxed = false
|
|
|
+ this.draggableResize=true
|
|
|
+ }
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
-<style scoped>
|
|
|
-/* .ant-upload.ant-upload-btn {
|
|
|
-} */
|
|
|
-
|
|
|
+<style scoped lang="scss">
|
|
|
.fullscreen-modal {
|
|
|
width: 100vw !important;
|
|
|
height: 100vh !important;
|
|
|
@@ -215,4 +305,119 @@ export default {
|
|
|
padding: 0px 0px 0px 0;
|
|
|
background-color: #dde5f6;
|
|
|
}
|
|
|
+
|
|
|
+:deep(.vdr) {
|
|
|
+ z-index: 10000 !important;
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.drag_btn {
|
|
|
+ background: #fff;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ button {
|
|
|
+ font-size: 20px;
|
|
|
+ width: 70px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.control-buttons {
|
|
|
+ background-color: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ position: absolute;
|
|
|
+ right: 8px;
|
|
|
+ top: 2px;
|
|
|
+ z-index: 100;
|
|
|
+}
|
|
|
+
|
|
|
+.control-button {
|
|
|
+ font-size: 16px;
|
|
|
+ margin-left: 8px; /* 按钮之间的间距 */
|
|
|
+ background: none;
|
|
|
+ border: none;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.draggable-title {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between; /* 子元素之间的间距均匀分布 */
|
|
|
+ align-items: center; /* 垂直居中 */
|
|
|
+ padding: 8px;
|
|
|
+ cursor: move;
|
|
|
+ background-color: #ffffff;
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 10;
|
|
|
+}
|
|
|
+
|
|
|
+.preview-left {
|
|
|
+ margin-left: 20px;
|
|
|
+ color: rgba(0, 0, 0, 0.88);
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+.preview-title {
|
|
|
+ margin: 0 auto;
|
|
|
+ color: rgba(0, 0, 0, 0.88);
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+.draggable-content {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ padding: 36px 22px 22px 22px;
|
|
|
+ cursor: move;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-resize {
|
|
|
+ background-color: #ffffff;
|
|
|
+ border: 1px dashed #ffffff; /* 虚线边框,蓝色 */
|
|
|
+ border-radius: 8px; /* 圆角边框 */
|
|
|
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影 */
|
|
|
+}
|
|
|
+
|
|
|
+.overlay {
|
|
|
+ position: absolute;
|
|
|
+ top: 60px;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ pointer-events: none; /* 防止鼠标事件干扰 iframe */
|
|
|
+}
|
|
|
+
|
|
|
+.horizontal {
|
|
|
+ height: 1px;
|
|
|
+ width: 100%;
|
|
|
+ border-color: #7cb305;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ borderWidth: 2px;
|
|
|
+ color: #0D366F;
|
|
|
+}
|
|
|
+
|
|
|
+.vertical {
|
|
|
+ display: inline-flex !important;
|
|
|
+ align-items: center !important;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ borderWidth: 2px;
|
|
|
+ color: #0D366F;
|
|
|
+ height: 100%;
|
|
|
+ border-color: #7cb305;
|
|
|
+ top: -92px;
|
|
|
+ z-index: 12;
|
|
|
+ margin-left: 70px;
|
|
|
+}
|
|
|
+
|
|
|
</style>
|