vue2-client 1.15.70 → 1.15.71-demo

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.15.70",
3
+ "version": "1.15.71-demo",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -234,7 +234,7 @@
234
234
  </span>
235
235
  <span v-else-if="item.slotType === 'action'" :key="'action-' + c_index">
236
236
  <template v-if="item.actionArr && item.actionArr.length > 0">
237
- <a-dropdown :getPopupContainer=" triggerNode => { return triggerNode.parentNode } ">
237
+ <a-dropdown placement="bottomCenter" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } ">
238
238
  <a class="ant-dropdown-link" @click="e => e.preventDefault()">
239
239
  {{ item.scopedSlots?.customRender || item.slotValue }} <a-icon type="down"/>
240
240
  </a>
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <div v-if="visible" class="preview-mask">
3
+ <div class="preview-container">
4
+ <img
5
+ :src="src"
6
+ :style="imgStyle"
7
+ class="preview-img"
8
+ @mousedown="startDrag"
9
+ draggable="false"
10
+ />
11
+ <div class="preview-actions">
12
+ <a-button @click="zoomIn">放大</a-button>
13
+ <a-button @click="zoomOut">缩小</a-button>
14
+ <a-button @click="rotateLeft">左旋转</a-button>
15
+ <a-button @click="rotateRight">右旋转</a-button>
16
+ <a-button @click="close">关闭</a-button>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { ref, computed } from 'vue'
24
+
25
+ const props = defineProps({
26
+ src: String,
27
+ visible: Boolean
28
+ })
29
+ const emits = defineEmits(['close'])
30
+
31
+ const scale = ref(1)
32
+ const rotate = ref(0)
33
+ const offset = ref({ x: 0, y: 0 })
34
+ const dragging = ref(false)
35
+ const dragStart = ref({ x: 0, y: 0 })
36
+
37
+ const imgStyle = computed(() => ({
38
+ transform: `scale(${scale.value}) rotate(${rotate.value}deg) translate(${offset.value.x}px, ${offset.value.y}px)`,
39
+ cursor: dragging.value ? 'grabbing' : 'grab'
40
+ }))
41
+
42
+ const zoomIn = () => scale.value += 0.2
43
+ const zoomOut = () => scale.value = Math.max(0.2, scale.value - 0.2)
44
+ const rotateLeft = () => rotate.value -= 90
45
+ const rotateRight = () => rotate.value += 90
46
+ const close = () => emits('close')
47
+
48
+ const startDrag = (e) => {
49
+ dragging.value = true
50
+ dragStart.value = { x: e.clientX - offset.value.x, y: e.clientY - offset.value.y }
51
+ document.addEventListener('mousemove', onDrag)
52
+ document.addEventListener('mouseup', stopDrag)
53
+ }
54
+ const onDrag = (e) => {
55
+ if (!dragging.value) return
56
+ offset.value = {
57
+ x: e.clientX - dragStart.value.x,
58
+ y: e.clientY - dragStart.value.y
59
+ }
60
+ }
61
+ const stopDrag = () => {
62
+ dragging.value = false
63
+ document.removeEventListener('mousemove', onDrag)
64
+ document.removeEventListener('mouseup', stopDrag)
65
+ }
66
+ </script>
67
+
68
+ <style scoped>
69
+ .preview-mask {
70
+ position: fixed;
71
+ z-index: 9999;
72
+ left: 0; top: 0; right: 0; bottom: 0;
73
+ background: rgba(0,0,0,0.7);
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ }
78
+ .preview-container {
79
+ position: relative;
80
+ background: #fff;
81
+ padding: 20px;
82
+ border-radius: 8px;
83
+ }
84
+ .preview-img {
85
+ max-width: 80vw;
86
+ max-height: 70vh;
87
+ user-select: none;
88
+ transition: transform 0.2s;
89
+ display: block;
90
+ margin: 0 auto;
91
+ }
92
+ .preview-actions {
93
+ margin-top: 16px;
94
+ display: flex;
95
+ justify-content: center;
96
+ gap: 10px;
97
+ }
98
+ </style>
@@ -17,7 +17,7 @@
17
17
  <h4>{{ item.days }}</h4>
18
18
  <div class="file-items">
19
19
  <div v-for="file in item.arrays" :key="file.id" class="file-card">
20
- <img :src="file.f_downloadpath" class="file-image" v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')" />
20
+ <img :src="file.f_downloadpath" class="file-image" v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')" @click="openPreview(file.f_downloadpath)" style="cursor:pointer" />
21
21
  <p>上传时间: {{ file.f_uploaddate }}</p>
22
22
  <p>操作员: {{ file.f_username }}</p>
23
23
  <p>分类: {{ file.fusetype }}</p>
@@ -29,12 +29,14 @@
29
29
  </div>
30
30
  </a-list-item>
31
31
  </a-list>
32
+ <ImagePreview :src="previewImg" :visible="previewVisible" @close="previewVisible = false" />
32
33
  </div>
33
34
  </template>
34
35
 
35
36
  <script>
36
37
  import { post } from '@vue2-client/services/api'
37
38
  import { del } from '@vue2-client/services/api/restTools'
39
+ import ImagePreview from './ImagePreview.vue'
38
40
  export default {
39
41
  props: {
40
42
  currUserInfo: {
@@ -42,13 +44,16 @@ export default {
42
44
  default: () => undefined
43
45
  }
44
46
  },
47
+ components: { ImagePreview },
45
48
  data () {
46
49
  return {
47
50
  upload_date: null,
48
51
  fusetype: null,
49
52
  files: [],
50
53
  fusetypes: [],
51
- isDelete: '0'
54
+ isDelete: '0',
55
+ previewVisible: false,
56
+ previewImg: ''
52
57
  }
53
58
  },
54
59
  methods: {
@@ -79,6 +84,10 @@ export default {
79
84
  },
80
85
  selfSearch () {
81
86
  this.getFiles()
87
+ },
88
+ openPreview (src) {
89
+ this.previewImg = src
90
+ this.previewVisible = true
82
91
  }
83
92
  },
84
93
  mounted () {