centaline-data-driven-v3 0.1.59 → 0.1.60
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/dist/centaline-data-driven-v3.umd.js +118 -118
- package/package.json +1 -1
- package/src/components/app/FormList.vue +215 -19
- package/src/components/web/File.vue +21 -2
- package/src/components/web/Form.vue +236 -8
- package/src/components/web/SearchList/SearchTable.vue +21 -5
- package/src/components/web/SearchList/TableToolbar.vue +9 -5
- package/src/components/web/SearchList.vue +1 -1
- package/src/components/web/ViewerFile/ViewerImage.vue +1 -1
- package/src/components/web/ViewerFile.vue +63 -21
- package/src/components/web/dialog.vue +18 -7
- package/src/loader/src/File.js +38 -22
- package/src/loader/src/SearchTable.js +58 -17
- package/src/main.js +3 -3
- package/src/utils/useDraggable.js +100 -0
- package/src/views/SearchList.vue +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="refForm" v-loading="loading"
|
|
3
3
|
:style="{ width: pageWidth ? pageWidth + 'px' : '100%', margin: 'auto', 'min-height': minHeight }">
|
|
4
|
-
<div style="display: flex; width: 100%;">
|
|
4
|
+
<div style="display: flex; width: 100%;" ref="leftContainerRef">
|
|
5
5
|
<div style="flex: 1; min-width: 0;">
|
|
6
6
|
<div v-if="model !== null && !loading" class="ct-form" :class="{ 'domDisabled': model.pageDisabled }"
|
|
7
7
|
:style="{ margin: openType != 'tree' ? '10px' : '0px' }">
|
|
@@ -194,9 +194,22 @@
|
|
|
194
194
|
@hideAI="AIToggle" :isVisible="showAI" :tablewidth="model.aiAttr.width">
|
|
195
195
|
|
|
196
196
|
</AIChat>
|
|
197
|
+
|
|
198
|
+
|
|
197
199
|
</div>
|
|
198
200
|
</div>
|
|
199
201
|
</template>
|
|
202
|
+
<div :style="{ flex: ' 0 0 ' + 650 + 'px', position: 'sticky', top: '0', 'box-shadow': '-10px 0 5px -9px rgba(0, 0, 0, 0.3)' }"
|
|
203
|
+
v-if="showViewerFile">
|
|
204
|
+
<div
|
|
205
|
+
:style="{ position: 'sticky', top: '0', height: (dialogHeight) + 'px', overflow: 'hidden', 'border-bottom-right-radius': '4px' }">
|
|
206
|
+
<ViewerFile :MediaAlbum="media.MediaAlbum" :groupIndex="media.groupIndex" :index="media.index"
|
|
207
|
+
:key="media.random" :flagLeft="media.flagLeft" @closeViewerFile="ViewerFileToggle(false)"
|
|
208
|
+
@ViewerFilechangeIndex="ViewerFilechangeIndex">
|
|
209
|
+
</ViewerFile>
|
|
210
|
+
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
200
213
|
|
|
201
214
|
</div>
|
|
202
215
|
<template v-if="model?.aiAttr?.showAI && !showAI">
|
|
@@ -205,13 +218,14 @@
|
|
|
205
218
|
:alt="model?.aiRouter.controlLabel" :title="model?.aiRouter.controlLabel">
|
|
206
219
|
</div>
|
|
207
220
|
</template>
|
|
221
|
+
|
|
208
222
|
<div style="min-height:200px" v-if="loading"></div>
|
|
209
223
|
<iframe :src="downloadUrl" style="height:0px;width:0px;border-width: 0px;display: none;"> </iframe>
|
|
210
224
|
|
|
211
225
|
</div>
|
|
212
226
|
</template>
|
|
213
227
|
<script lang="ts" setup>
|
|
214
|
-
import { ref, nextTick, onUpdated, onDeactivated, onMounted, onBeforeUnmount,provide } from 'vue'
|
|
228
|
+
import { ref, nextTick, onUpdated, onDeactivated, onMounted, onBeforeUnmount, provide } from 'vue'
|
|
215
229
|
import { RouterClickHandler } from '../../utils/mixins';
|
|
216
230
|
import common from '../../utils/common'
|
|
217
231
|
import Form from '../../loader/src/Form'
|
|
@@ -220,7 +234,9 @@ import { useRouter } from 'vue-router';
|
|
|
220
234
|
import util from '../../utils/pub-use'
|
|
221
235
|
import Enum from '../../utils/Enum';
|
|
222
236
|
import AIChat from '../web/AIChat.vue';
|
|
223
|
-
|
|
237
|
+
import ViewerFile from '../web/ViewerFile.vue';
|
|
238
|
+
|
|
239
|
+
const emit = defineEmits(['loaded', 'failLoad', 'submit', 'ToggleWdth'])
|
|
224
240
|
const props = defineProps({
|
|
225
241
|
api: String,
|
|
226
242
|
vmodel: Object,
|
|
@@ -283,6 +299,14 @@ const props = defineProps({
|
|
|
283
299
|
dialoWidth: Number,
|
|
284
300
|
listHeight: Number,
|
|
285
301
|
})
|
|
302
|
+
const media = ref({
|
|
303
|
+
MediaAlbum: [],
|
|
304
|
+
groupIndex: 0,
|
|
305
|
+
index: 0,
|
|
306
|
+
flagLeft: false,
|
|
307
|
+
random: Math.random()
|
|
308
|
+
})
|
|
309
|
+
const showViewerFile = ref(false)
|
|
286
310
|
const itemKey = ref(1)
|
|
287
311
|
const router = useRouter()
|
|
288
312
|
const loading = ref(true)
|
|
@@ -292,6 +316,7 @@ const isScroll = ref(false)
|
|
|
292
316
|
const isWebScroll = ref(false)
|
|
293
317
|
const Fields = ref()
|
|
294
318
|
const refForm = ref()
|
|
319
|
+
|
|
295
320
|
const downloadUrl = ref('')
|
|
296
321
|
const minHeight = ref('auto')
|
|
297
322
|
const showAI = ref(false);
|
|
@@ -366,11 +391,11 @@ function init() {
|
|
|
366
391
|
}
|
|
367
392
|
if (typeof props.api !== 'undefined') {
|
|
368
393
|
//根据接口获取数据
|
|
369
|
-
Form.loadFormApi(props.api, load, props.apiParam, failLoad, false,props.appRootUrl);
|
|
394
|
+
Form.loadFormApi(props.api, load, props.apiParam, failLoad, false, props.appRootUrl);
|
|
370
395
|
}
|
|
371
396
|
else if (typeof props.source !== 'undefined') {
|
|
372
397
|
//根据modelFrom获取数据
|
|
373
|
-
load(Form.loadFromModel(props.source,false,props.appRootUrl));
|
|
398
|
+
load(Form.loadFromModel(props.source, false, props.appRootUrl));
|
|
374
399
|
}
|
|
375
400
|
else if (props.vmodel) {
|
|
376
401
|
load(props.vmodel);
|
|
@@ -764,20 +789,223 @@ function setCss() {
|
|
|
764
789
|
|
|
765
790
|
function AIToggle() {
|
|
766
791
|
showAI.value = !showAI.value;
|
|
792
|
+
if (showAI.value) {
|
|
793
|
+
if (showViewerFile.value) {
|
|
794
|
+
ViewerFileToggle(false, [], 0, 0);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
767
798
|
let width = model.value.aiAttr.width;
|
|
768
799
|
dialogHeight.value = (props.dialogHeight || (window.innerHeight - 60));
|
|
769
|
-
emit('
|
|
800
|
+
emit('ToggleWdth', (showAI.value ? width : -width));
|
|
801
|
+
}
|
|
802
|
+
const getVisibleDimensions = () => {
|
|
803
|
+
if (!refForm.value) return { width: 0, height: 0 };
|
|
804
|
+
const rect = refForm.value.getBoundingClientRect();
|
|
805
|
+
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
806
|
+
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
807
|
+
|
|
808
|
+
const visibleTop = Math.max(0, rect.top);
|
|
809
|
+
const visibleBottom = Math.min(viewHeight, rect.bottom);
|
|
810
|
+
const visibleLeft = Math.max(0, rect.left);
|
|
811
|
+
const visibleRight = Math.min(viewWidth, rect.right);
|
|
812
|
+
|
|
813
|
+
return {
|
|
814
|
+
width: Math.max(0, visibleRight - visibleLeft),
|
|
815
|
+
height: Math.max(0, visibleBottom - visibleTop)-60
|
|
816
|
+
};
|
|
817
|
+
};
|
|
818
|
+
function ViewerFileToggle(isOpen, mediaAlbum, groupIndex, index) {
|
|
819
|
+
if (isOpen) {
|
|
820
|
+
media.value = { MediaAlbum: mediaAlbum, groupIndex, index, flagLeft: false, random: Math.random() };
|
|
821
|
+
if (showAI.value) {
|
|
822
|
+
AIToggle();
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (showViewerFile.value != isOpen) {
|
|
826
|
+
showViewerFile.value = isOpen;
|
|
827
|
+
let width = 650;
|
|
828
|
+
dialogHeight.value = getVisibleDimensions().height || parseInt(minHeight.value) || window.innerHeight - 60;
|
|
829
|
+
emit('ToggleWdth', (showViewerFile.value ? width : -width));
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
provide('onViewerFileToggle', ViewerFileToggle)
|
|
833
|
+
function ViewerFilechangeIndex({ groupIndex, index }) {
|
|
834
|
+
if (media.value) {
|
|
835
|
+
media.value.groupIndex = groupIndex;
|
|
836
|
+
media.value.index = index;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
function ChangeFileList(mediaAlbum, groupIndex, index) {
|
|
841
|
+
if (!showViewerFile.value) {
|
|
842
|
+
return;
|
|
843
|
+
} else {
|
|
844
|
+
if (mediaAlbum[0].medias.length <= 0) {
|
|
845
|
+
ViewerFileToggle(false);
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
const oldMedia = media.value;
|
|
850
|
+
let newGroupIndex, newIndex, shouldShow;
|
|
851
|
+
|
|
852
|
+
// 情况1:没有旧记录,直接用传入索引,无效则找第一张
|
|
853
|
+
if (!oldMedia || !oldMedia.MediaAlbum) {
|
|
854
|
+
if (validatePosition(mediaAlbum, groupIndex, index)) {
|
|
855
|
+
newGroupIndex = groupIndex;
|
|
856
|
+
newIndex = index;
|
|
857
|
+
shouldShow = true;
|
|
858
|
+
} else {
|
|
859
|
+
const first = findFirstValidPosition(mediaAlbum);
|
|
860
|
+
if (first) {
|
|
861
|
+
newGroupIndex = first.groupIndex;
|
|
862
|
+
newIndex = first.index;
|
|
863
|
+
shouldShow = true;
|
|
864
|
+
} else {
|
|
865
|
+
// 整个相册无图,直接关闭查看器,但依然要更新 MediaAlbum
|
|
866
|
+
newGroupIndex = 0;
|
|
867
|
+
newIndex = 0;
|
|
868
|
+
shouldShow = false;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
} else {
|
|
872
|
+
// 取出旧图片
|
|
873
|
+
const oldAlbumList = oldMedia.MediaAlbum;
|
|
874
|
+
const oldGroup = oldAlbumList && oldAlbumList[oldMedia.groupIndex];
|
|
875
|
+
const oldFile = oldGroup && oldGroup.medias && oldGroup.medias[oldMedia.index];
|
|
876
|
+
|
|
877
|
+
if (oldFile) {
|
|
878
|
+
// 尝试在新相册中定位旧图
|
|
879
|
+
const found = findFileInAlbum(mediaAlbum, oldFile);
|
|
880
|
+
if (found) {
|
|
881
|
+
// 找到了,移动到新位置
|
|
882
|
+
newGroupIndex = found.groupIndex;
|
|
883
|
+
newIndex = found.index;
|
|
884
|
+
shouldShow = true;
|
|
885
|
+
} else {
|
|
886
|
+
// 旧图被删,回退
|
|
887
|
+
const fallback = fallbackPosition(mediaAlbum, oldMedia.groupIndex, oldMedia.index);
|
|
888
|
+
newGroupIndex = fallback.groupIndex;
|
|
889
|
+
newIndex = fallback.index;
|
|
890
|
+
shouldShow = fallback.show;
|
|
891
|
+
}
|
|
892
|
+
} else {
|
|
893
|
+
// 旧记录无效,同样回退
|
|
894
|
+
const fallback = fallbackPosition(mediaAlbum, oldMedia.groupIndex, oldMedia.index);
|
|
895
|
+
newGroupIndex = fallback.groupIndex;
|
|
896
|
+
newIndex = fallback.index;
|
|
897
|
+
shouldShow = fallback.show;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
ViewerFileToggle(showViewerFile.value, mediaAlbum, newGroupIndex, newIndex);
|
|
770
901
|
}
|
|
902
|
+
provide('ChangeFileList', ChangeFileList)
|
|
771
903
|
|
|
904
|
+
function validatePosition(albumList, gIdx, idx) {
|
|
905
|
+
if (!albumList || gIdx < 0 || gIdx >= albumList.length) {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
var group = albumList[gIdx];
|
|
909
|
+
var medias = group && group.medias;
|
|
910
|
+
return medias && idx >= 0 && idx < medias.length;
|
|
911
|
+
}
|
|
912
|
+
function findFirstValidPosition(albumList) {
|
|
913
|
+
if (!albumList) {
|
|
914
|
+
return null;
|
|
915
|
+
}
|
|
916
|
+
for (var g = 0; g < albumList.length; g++) {
|
|
917
|
+
var group = albumList[g];
|
|
918
|
+
var medias = group && group.medias;
|
|
919
|
+
if (medias && medias.length > 0) {
|
|
920
|
+
return { groupIndex: g, index: 0 };
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
function findFileInAlbum(albumList, targetFile) {
|
|
926
|
+
if (!albumList) {
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
// 先按引用查找
|
|
930
|
+
for (var g = 0; g < albumList.length; g++) {
|
|
931
|
+
var medias = albumList[g].medias;
|
|
932
|
+
if (!medias) continue;
|
|
933
|
+
for (var i = 0; i < medias.length; i++) {
|
|
934
|
+
if (medias[i] === targetFile) {
|
|
935
|
+
return { groupIndex: g, index: i };
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
// 如果引用匹配不到,尝试用 id(如果存在)
|
|
940
|
+
if (targetFile && targetFile.id != null) {
|
|
941
|
+
for (var g2 = 0; g2 < albumList.length; g2++) {
|
|
942
|
+
var medias2 = albumList[g2].medias;
|
|
943
|
+
if (!medias2) continue;
|
|
944
|
+
for (var i2 = 0; i2 < medias2.length; i2++) {
|
|
945
|
+
if (medias2[i2].id === targetFile.id) {
|
|
946
|
+
return { groupIndex: g2, index: i2 };
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
function fallbackPosition(albumList, prefGroup, prefIndex) {
|
|
954
|
+
if (!albumList || albumList.length === 0) {
|
|
955
|
+
return { groupIndex: 0, index: 0, show: false };
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// 确保参考相册索引在有效范围内
|
|
959
|
+
var gIdx = Math.min(prefGroup, albumList.length - 1);
|
|
960
|
+
var group = albumList[gIdx];
|
|
961
|
+
var medias = group && group.medias ? group.medias : [];
|
|
962
|
+
|
|
963
|
+
// 1. 同相册内回退
|
|
964
|
+
if (medias.length > 0) {
|
|
965
|
+
var newIdx;
|
|
966
|
+
if (prefIndex > 0 && prefIndex <= medias.length) {
|
|
967
|
+
// 优先上一张
|
|
968
|
+
newIdx = prefIndex - 1;
|
|
969
|
+
} else if (prefIndex === 0 && medias.length > 1) {
|
|
970
|
+
// 第一张被删了,取下一张(索引 1)
|
|
971
|
+
newIdx = 1;
|
|
972
|
+
} else {
|
|
973
|
+
// 只剩这一张,还是它
|
|
974
|
+
newIdx = 0;
|
|
975
|
+
}
|
|
976
|
+
return { groupIndex: gIdx, index: newIdx, show: true };
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// 2. 向前找非空相册,取最后一张
|
|
980
|
+
for (var g = gIdx - 1; g >= 0; g--) {
|
|
981
|
+
var m = albumList[g].medias || [];
|
|
982
|
+
if (m.length > 0) {
|
|
983
|
+
return { groupIndex: g, index: m.length - 1, show: true };
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// 3. 向后找非空相册,取第一张
|
|
988
|
+
for (var g2 = gIdx + 1; g2 < albumList.length; g2++) {
|
|
989
|
+
var m2 = albumList[g2].medias || [];
|
|
990
|
+
if (m2.length > 0) {
|
|
991
|
+
return { groupIndex: g2, index: 0, show: true };
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// 整个相册没有任何图片了
|
|
996
|
+
return { groupIndex: 0, index: 0, show: false };
|
|
997
|
+
}
|
|
772
998
|
|
|
773
999
|
function buttonsWidth() {
|
|
774
1000
|
let rtn = '100%';
|
|
775
1001
|
if (showAI.value) {
|
|
776
|
-
rtn = props.dialoWidth - model.value.aiAttr.width - 4 + 'px';
|
|
1002
|
+
rtn = (props.dialoWidth||getVisibleDimensions().width) - model.value.aiAttr.width - 4 + 'px';
|
|
1003
|
+
}
|
|
1004
|
+
else if (showViewerFile.value) {
|
|
1005
|
+
rtn = (props.dialoWidth||getVisibleDimensions().width) - 650 - 4 + 'px';
|
|
777
1006
|
}
|
|
778
1007
|
else if (props.pageWidth) {
|
|
779
1008
|
rtn = props.pageWidth + 'px';
|
|
780
|
-
|
|
781
1009
|
}
|
|
782
1010
|
|
|
783
1011
|
return rtn;
|
|
@@ -398,7 +398,7 @@ function searchComplate(m, defaultSearch) {
|
|
|
398
398
|
searchEnd.value = Date.now();
|
|
399
399
|
isLoading.value = false;
|
|
400
400
|
tableLoading.value = false;
|
|
401
|
-
},null,props.appRootUrl);
|
|
401
|
+
}, null, props.appRootUrl);
|
|
402
402
|
}
|
|
403
403
|
if (typeof props.source !== "undefined") {
|
|
404
404
|
load(SearchTable.loadSearchTableModel(props.source));
|
|
@@ -412,9 +412,9 @@ function searchComplate(m, defaultSearch) {
|
|
|
412
412
|
//初始化数据
|
|
413
413
|
function load(data) {
|
|
414
414
|
model.value = data;
|
|
415
|
-
model.value.$vue = { searchStrat, searchEnd, downloadUrl, loadStats, setTableHeight, updateCurrentRow, doAction, itemKey, refreshTableColumns, calculatingRowHeight, emit, operationLoading, getPage, toolbarClickHandler,closeTabThen };
|
|
415
|
+
model.value.$vue = { searchStrat, searchEnd, downloadUrl, loadStats, setTableHeight, updateCurrentRow, doAction, itemKey, refreshTableColumns, calculatingRowHeight, emit, operationLoading, getPage, toolbarClickHandler, closeTabThen };
|
|
416
416
|
model.value.isIframe = props.isIframe
|
|
417
|
-
model.value.appendToBody=props.appendToBody
|
|
417
|
+
model.value.appendToBody = props.appendToBody
|
|
418
418
|
model.value.isPageInSideBar = false
|
|
419
419
|
model.value.columnName = null
|
|
420
420
|
model.value.columnGroupId = null
|
|
@@ -973,6 +973,7 @@ function thMouseDownHandle(ev, colIndex) {
|
|
|
973
973
|
}
|
|
974
974
|
//查询对应页的数据
|
|
975
975
|
function getPage(index, flagRefreshRowHandle) {
|
|
976
|
+
getRetain();
|
|
976
977
|
if (refTableParent.value) {
|
|
977
978
|
refTableParent.value.scrollTop = 0;
|
|
978
979
|
refTableParent.value.scrollLeft = 0;
|
|
@@ -997,8 +998,12 @@ function getPage(index, flagRefreshRowHandle) {
|
|
|
997
998
|
getScrollAttr();
|
|
998
999
|
}
|
|
999
1000
|
setfixedSize();
|
|
1001
|
+
model.value.selectIndex = 0;
|
|
1002
|
+
model.value._lastRowspan = null;
|
|
1000
1003
|
if (index === 1) {
|
|
1001
1004
|
SearchTable.setButtonsDisabledByRowClick(model.value);
|
|
1005
|
+
SearchTable.setButtonsDisabled(model.value);
|
|
1006
|
+
model.value.selectAll = false;
|
|
1002
1007
|
}
|
|
1003
1008
|
});
|
|
1004
1009
|
}
|
|
@@ -1303,7 +1308,7 @@ function refreshTableColumns(data) {
|
|
|
1303
1308
|
searchStats = refTableStats.value.getsearchStats();
|
|
1304
1309
|
}
|
|
1305
1310
|
if (data) {
|
|
1306
|
-
load(SearchTable.loadSearchTableModel(data, model.value.searchModel, false, props.api,null,props.appRootUrl));
|
|
1311
|
+
load(SearchTable.loadSearchTableModel(data, model.value.searchModel, false, props.api, null, props.appRootUrl));
|
|
1307
1312
|
}
|
|
1308
1313
|
else {
|
|
1309
1314
|
if (refTableStats.value) {
|
|
@@ -1311,7 +1316,7 @@ function refreshTableColumns(data) {
|
|
|
1311
1316
|
getPage(1, true);
|
|
1312
1317
|
}
|
|
1313
1318
|
else {
|
|
1314
|
-
SearchTable.loadSearchTableApi(props.api, load, searchModel, true,null,null,null,props.appRootUrl);
|
|
1319
|
+
SearchTable.loadSearchTableApi(props.api, load, searchModel, true, null, null, null, props.appRootUrl);
|
|
1315
1320
|
}
|
|
1316
1321
|
}
|
|
1317
1322
|
model.value.searchStats = searchStats;
|
|
@@ -1657,6 +1662,17 @@ function closeTabThen(ev) {
|
|
|
1657
1662
|
}
|
|
1658
1663
|
}
|
|
1659
1664
|
|
|
1665
|
+
function getRetain() {
|
|
1666
|
+
model.value.isRetain = false
|
|
1667
|
+
let field = model.value.buttons.find((b) => {
|
|
1668
|
+
return b.key.toLowerCase() === 'Retain'.toLowerCase();
|
|
1669
|
+
});
|
|
1670
|
+
if (field) {
|
|
1671
|
+
if (field.code1) {
|
|
1672
|
+
model.value.isRetain = true;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1660
1676
|
|
|
1661
1677
|
defineExpose({
|
|
1662
1678
|
model,
|
|
@@ -3,16 +3,18 @@
|
|
|
3
3
|
<div v-if="buttonsLeft && buttonsLeft.length > 0" class="bool_btn_l">
|
|
4
4
|
<ul>
|
|
5
5
|
<li v-for="btn in buttonsLeft" class="ToolbarButton" :class="{ btn_r: btn.isRight }">
|
|
6
|
-
<component :is="btn.is" :vmodel="btn" @fieldClick="clickHandler(btn)"
|
|
7
|
-
v-if="btn.show" :parameterAction="parameterAction"
|
|
6
|
+
<component :is="btn.is" :vmodel="btn" @fieldClick="clickHandler(btn)"
|
|
7
|
+
@importComplete="importComplete" v-if="btn.show" :parameterAction="parameterAction"
|
|
8
|
+
:fileData="getFileData(btn)"></component>
|
|
8
9
|
</li>
|
|
9
10
|
</ul>
|
|
10
11
|
</div>
|
|
11
12
|
<div v-if="buttonsright && buttonsright.length > 0" class="bool_btn_r">
|
|
12
13
|
<ul>
|
|
13
14
|
<li v-for="btn in buttonsright" class="ToolbarButton" :class="{ btn_r: btn.isRight }">
|
|
14
|
-
<component :is="btn.is" :vmodel="btn" @fieldClick="clickHandler(btn,)"
|
|
15
|
-
v-if="btn.show" :parameterAction="parameterAction"
|
|
15
|
+
<component :is="btn.is" :vmodel="btn" @fieldClick="clickHandler(btn,)"
|
|
16
|
+
@importComplete="importComplete" v-if="btn.show" :parameterAction="parameterAction"
|
|
17
|
+
:fileData="getFileData(btn)"></component>
|
|
16
18
|
</li>
|
|
17
19
|
</ul>
|
|
18
20
|
</div>
|
|
@@ -37,7 +39,9 @@ props.buttons.forEach(v => {
|
|
|
37
39
|
}
|
|
38
40
|
});
|
|
39
41
|
function clickHandler(btn) {
|
|
40
|
-
|
|
42
|
+
if (btn.key.toLowerCase() != 'Retain'.toLocaleLowerCase()) {
|
|
43
|
+
emit("click", btn);
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
function importComplete(res, field) {
|
|
43
47
|
emit("importComplete", res, field);
|
|
@@ -161,6 +161,7 @@ function init() {
|
|
|
161
161
|
if (props.apiParam && props.apiParam.isIframe && props.apiParam.isIframe == 'true') {
|
|
162
162
|
isIframe.value = true;
|
|
163
163
|
}
|
|
164
|
+
window.addEventListener("resize", resizeSearchList);
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
function screenLoaded(defaultSearch) {
|
|
@@ -282,7 +283,6 @@ function tableLoaded() {
|
|
|
282
283
|
sideMenuClickHandler(status);
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
|
-
window.addEventListener("resize", resizeSearchList);
|
|
286
286
|
}
|
|
287
287
|
else {
|
|
288
288
|
flagSideBarOfData.value = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="Imagebox" @mousewheel="bagimg($event)" v-loading="loading">
|
|
2
|
+
<div class="Imagebox" @mousewheel.stop.prevent="bagimg($event)" v-loading="loading">
|
|
3
3
|
<img id="ViewerImage" class="scaleimg" border="0" @load="complete()" v-bind:style="{
|
|
4
4
|
top: params.top + 'px', left: params.left + 'px',
|
|
5
5
|
transform:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div style="height: 100%" id="viewer-file" ref="refviewerfile" @contextmenu="handleMouse" class="viewer-file ccai">
|
|
3
3
|
<el-container style="height: 100%; border: 1px solid #eee">
|
|
4
|
-
<el-aside style="background-color: rgb(238, 241, 246)" class="ccai-aside">
|
|
4
|
+
<el-aside style="background-color: rgb(238, 241, 246)" class="ccai-aside" v-if="flagLeft">
|
|
5
5
|
<div style="height: 100%" class="viewerMenu">
|
|
6
6
|
<el-menu :default-openeds="openeds" :default-active="activeitem" style="height: 100%">
|
|
7
7
|
<el-sub-menu :key="groupIndex" :index="groupIndex.toString()"
|
|
@@ -28,32 +28,44 @@
|
|
|
28
28
|
</div>
|
|
29
29
|
</el-aside>
|
|
30
30
|
<el-main ref="refdisplayArea" v-loading="downloadLoading" element-loading-spinner="el-icon-loading"
|
|
31
|
-
:element-loading-custom-class="'cloading'">
|
|
31
|
+
:element-loading-custom-class="'cloading'" style="background-color: white;overflow: hidden;position: relative;">
|
|
32
|
+
<div v-if="!flagLeft" style="position: absolute; top: 10px; left: 10px;cursor: pointer;color:red"
|
|
33
|
+
@click="closeViewerFile">
|
|
34
|
+
<el-icon size="20">
|
|
35
|
+
<CircleClose />
|
|
36
|
+
</el-icon>
|
|
37
|
+
|
|
38
|
+
</div>
|
|
32
39
|
<div class="cont" v-if="resultObject">
|
|
33
40
|
<div style="padding-right:10px;" v-if="mediaLabelShow">
|
|
34
41
|
<div class="enlarge-picture " v-if="itemFile.mediaLabelName">
|
|
35
|
-
<span class="" style="width:80px;">{{common.LocalizedString('附件类型','附件類型')}} : </span>
|
|
42
|
+
<span class="" style="width:80px;">{{ common.LocalizedString('附件类型', '附件類型') }} : </span>
|
|
36
43
|
<lable style="font-weight: bold;">{{ itemFile.mediaLabelName }}</lable>
|
|
37
44
|
</div>
|
|
38
45
|
<div class="enlarge-picture" v-if="itemFile.mediaDescCN">
|
|
39
|
-
<span style="width:80px;">{{common.LocalizedString('中文描述','中文描述')}} : </span>
|
|
46
|
+
<span style="width:80px;">{{ common.LocalizedString('中文描述', '中文描述') }} : </span>
|
|
40
47
|
<lable style="font-weight: bold;">{{ itemFile.mediaDescCN }}</lable>
|
|
41
48
|
</div>
|
|
42
49
|
<div class="enlarge-picture" v-if="itemFile.mediaDescEN">
|
|
43
|
-
<span style="width:80px;">{{common.LocalizedString('英文描述','英文描述')}} : </span>
|
|
50
|
+
<span style="width:80px;">{{ common.LocalizedString('英文描述', '英文描述') }} : </span>
|
|
44
51
|
<lable style="font-weight: bold;">{{ itemFile.mediaDescEN }}</lable>
|
|
45
52
|
</div>
|
|
46
53
|
<div class="enlarge-picture" v-if="itemFile.mediaUploadEmployeeDesc">
|
|
47
|
-
<span style="width:80px;">{{common.LocalizedString('来源描述','來源描述')}} : </span>
|
|
54
|
+
<span style="width:80px;">{{ common.LocalizedString('来源描述', '來源描述') }} : </span>
|
|
48
55
|
<lable style="font-weight: bold;">{{ itemFile.mediaUploadEmployeeDesc }}</lable>
|
|
49
56
|
</div>
|
|
50
57
|
</div>
|
|
51
|
-
<div class="toggler" @click="mediaLabelShow
|
|
58
|
+
<div class="toggler" @click="mediaLabelShow = !mediaLabelShow"
|
|
59
|
+
v-if="itemFile.mediaLabelName || itemFile.mediaDescCN || itemFile.mediaDescEN || itemFile.mediaUploadEmployeeDesc">
|
|
52
60
|
<span class="glyphicon glyphicon-chevron-right" v-if="mediaLabelShow">
|
|
53
|
-
<el-icon color="#000000"
|
|
61
|
+
<el-icon color="#000000">
|
|
62
|
+
<ArrowRightBold />
|
|
63
|
+
</el-icon>
|
|
54
64
|
</span>
|
|
55
65
|
<span class="glyphicon glyphicon-chevron-left" v-if="!mediaLabelShow">
|
|
56
|
-
<el-icon color="#000000"
|
|
66
|
+
<el-icon color="#000000">
|
|
67
|
+
<ArrowLeftBold />
|
|
68
|
+
</el-icon>
|
|
57
69
|
</span>
|
|
58
70
|
</div>
|
|
59
71
|
</div>
|
|
@@ -118,7 +130,7 @@
|
|
|
118
130
|
<template v-else>
|
|
119
131
|
<div class="viewerContent" style="max-height: 200px; text-align: center">
|
|
120
132
|
<a :href="resultObject" target="_blank">
|
|
121
|
-
<img :src="(itemFile.thumbnailUrl||itemFile.url)" /><br />{{
|
|
133
|
+
<img :src="(itemFile.thumbnailUrl || itemFile.url)" /><br />{{
|
|
122
134
|
itemFile.mediaLabelName || itemFile.fileName
|
|
123
135
|
}}
|
|
124
136
|
</a>
|
|
@@ -126,7 +138,8 @@
|
|
|
126
138
|
</template>
|
|
127
139
|
</template>
|
|
128
140
|
<!--p360-->
|
|
129
|
-
<template
|
|
141
|
+
<template
|
|
142
|
+
v-else-if="itemFile.mediaTypeID == '7' || (itemFile.mediaTypeID + '').toLowerCase() == 'p360'">
|
|
130
143
|
<viewerP360 ref="refviewerP360" :height="displayAreaHeight" :width="displayAreaWidth"
|
|
131
144
|
:imgUrl="resultObject" />
|
|
132
145
|
</template>
|
|
@@ -144,6 +157,8 @@
|
|
|
144
157
|
<div class="magnify-footer" :style="{
|
|
145
158
|
width: displayAreaWidth + 'px',
|
|
146
159
|
bottom: displayAreabtm + 10 + 'px',
|
|
160
|
+
position: !flagLeft ? 'absolute' : 'fixed',
|
|
161
|
+
|
|
147
162
|
}">
|
|
148
163
|
<div class="magnify-toolbar" :style="{ 'margin-left': displayArealeft + 'px' }">
|
|
149
164
|
|
|
@@ -201,14 +216,18 @@ import common from '../../utils/common';
|
|
|
201
216
|
import viewerImage from './ViewerFile/ViewerImage.vue';
|
|
202
217
|
import viewerPDF from './ViewerFile/ViewerPDFjs.vue';
|
|
203
218
|
import viewerP360 from './ViewerFile/viewerP360.vue';
|
|
219
|
+
const emit = defineEmits(['closeViewerFile', 'ViewerFilechangeIndex'])
|
|
204
220
|
|
|
205
221
|
const props = defineProps({
|
|
206
222
|
MediaAlbum: Array,
|
|
207
223
|
groupIndex: Number,
|
|
208
224
|
index: Number,
|
|
225
|
+
flagLeft: {
|
|
226
|
+
type: Boolean,
|
|
227
|
+
default: true
|
|
228
|
+
}
|
|
209
229
|
})
|
|
210
230
|
|
|
211
|
-
|
|
212
231
|
const refviewerfile = ref()
|
|
213
232
|
const refdisplayArea = ref()
|
|
214
233
|
const refviewerImage = ref()
|
|
@@ -227,8 +246,8 @@ const displayArealeft = ref(0)
|
|
|
227
246
|
const displayAreaHeight = ref(0)
|
|
228
247
|
const downloadUrl = ref("")
|
|
229
248
|
const downloadLoading = ref(false)
|
|
230
|
-
const mediaLabelShow=ref(false)
|
|
231
|
-
const qrtimer=ref(null)
|
|
249
|
+
const mediaLabelShow = ref(false)
|
|
250
|
+
const qrtimer = ref(null)
|
|
232
251
|
|
|
233
252
|
groupCountLen.value = 0;
|
|
234
253
|
props.MediaAlbum.forEach((item, n) => {
|
|
@@ -245,11 +264,18 @@ onMounted(() => {
|
|
|
245
264
|
displayArealeft.value = DomLeft();
|
|
246
265
|
displayAreabtm.value = DomTop(refdisplayArea.value.$el);
|
|
247
266
|
displayAreaHeight.value = refdisplayArea.value.$el.offsetHeight;
|
|
267
|
+
if (!props.flagLeft) {
|
|
268
|
+
displayAreaHeight.value = displayAreaHeight.value - 5;
|
|
269
|
+
}
|
|
248
270
|
window.onresize = () => {
|
|
249
271
|
displayAreaWidth.value = DomWidth();
|
|
250
272
|
displayArealeft.value = DomLeft();
|
|
251
273
|
displayAreabtm.value = DomTop(refdisplayArea.value.$el);
|
|
274
|
+
|
|
252
275
|
displayAreaHeight.value = refdisplayArea.value.$el.offsetHeight;
|
|
276
|
+
if (!props.flagLeft) {
|
|
277
|
+
displayAreaHeight.value = displayAreaHeight.value - 5;
|
|
278
|
+
}
|
|
253
279
|
};
|
|
254
280
|
|
|
255
281
|
if (
|
|
@@ -258,7 +284,7 @@ onMounted(() => {
|
|
|
258
284
|
props.groupIndex > -1 &&
|
|
259
285
|
props.index > -1
|
|
260
286
|
) {
|
|
261
|
-
var item = props.MediaAlbum[props.groupIndex]
|
|
287
|
+
var item = props.MediaAlbum[props.groupIndex]?.medias[props.index];
|
|
262
288
|
handleClick(item, props.groupIndex, props.index);
|
|
263
289
|
}
|
|
264
290
|
})
|
|
@@ -304,6 +330,9 @@ function handleMouse(e) {
|
|
|
304
330
|
e.preventDefault();
|
|
305
331
|
}
|
|
306
332
|
function DomWidth() {
|
|
333
|
+
if (!props.flagLeft) {
|
|
334
|
+
return refdisplayArea.value.$el.offsetWidth - 40;
|
|
335
|
+
}
|
|
307
336
|
let arrLength = window.innerWidth - refviewerfile.value.offsetWidth;
|
|
308
337
|
arrLength = arrLength > 0 ? arrLength : 0;
|
|
309
338
|
var Width =
|
|
@@ -315,6 +344,9 @@ function DomWidth() {
|
|
|
315
344
|
return Width;
|
|
316
345
|
}
|
|
317
346
|
function DomTop() {
|
|
347
|
+
if (!props.flagLeft) {
|
|
348
|
+
return -65;
|
|
349
|
+
}
|
|
318
350
|
const height = window.innerHeight; //可视区窗口高度
|
|
319
351
|
const curDomHeight = refviewerfile.value.offsetHeight;
|
|
320
352
|
// const curDomHeight = dom.getBoundingClientRect().height
|
|
@@ -324,6 +356,9 @@ function DomTop() {
|
|
|
324
356
|
return curDomBottom;
|
|
325
357
|
}
|
|
326
358
|
function DomLeft() {
|
|
359
|
+
if (!props.flagLeft) {
|
|
360
|
+
return 65;
|
|
361
|
+
}
|
|
327
362
|
let arrLength = window.innerWidth - refviewerfile.value.offsetWidth;
|
|
328
363
|
arrLength = arrLength > 0 ? arrLength : 0;
|
|
329
364
|
var Width =
|
|
@@ -341,7 +376,8 @@ function handleClick(item, groupIndex, index) {
|
|
|
341
376
|
activeGroup.value = groupIndex;
|
|
342
377
|
itemFile.value = item;
|
|
343
378
|
activeitem.value = groupIndex + "-" + index;
|
|
344
|
-
resultObject.value = itemFile.value
|
|
379
|
+
resultObject.value = itemFile.value?.mediaUrl;
|
|
380
|
+
emit('ViewerFilechangeIndex', { groupIndex: groupIndex, index: index })
|
|
345
381
|
}
|
|
346
382
|
function jump(n) {
|
|
347
383
|
var item = {};
|
|
@@ -421,12 +457,16 @@ function zoom(n) {
|
|
|
421
457
|
function enterFullscreen(n) {
|
|
422
458
|
refviewerP360.value.enterFullscreen(n);
|
|
423
459
|
}
|
|
460
|
+
|
|
461
|
+
function closeViewerFile() {
|
|
462
|
+
emit('closeViewerFile')
|
|
463
|
+
}
|
|
424
464
|
onUnmounted(() => {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
465
|
+
window.onresize = null;
|
|
466
|
+
if (qrtimer.value) {
|
|
467
|
+
clearTimeout(qrtimer.value);
|
|
468
|
+
qrtimer.value = null;
|
|
469
|
+
}
|
|
430
470
|
})
|
|
431
471
|
</script>
|
|
432
472
|
<style scoped>
|
|
@@ -503,6 +543,7 @@ html {
|
|
|
503
543
|
.enlarge-picture {
|
|
504
544
|
padding: 5px 10px;
|
|
505
545
|
}
|
|
546
|
+
|
|
506
547
|
.toggler {
|
|
507
548
|
-webkit-border-top-right-radius: 4px;
|
|
508
549
|
-webkit-border-bottom-right-radius: 4px;
|
|
@@ -522,6 +563,7 @@ html {
|
|
|
522
563
|
cursor: pointer;
|
|
523
564
|
position: absolute;
|
|
524
565
|
}
|
|
566
|
+
|
|
525
567
|
.glyphicon {
|
|
526
568
|
margin: 15px 0px;
|
|
527
569
|
position: relative;
|