提交 96e9c6bc authored 作者: 龙菲's avatar 龙菲

完善以图搜图界面、增加以已存在的图片进行搜索;优化文物详情页整图布局和逻辑

上级 ba1b6613
...@@ -313,3 +313,65 @@ li { ...@@ -313,3 +313,65 @@ li {
} }
} }
} }
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar:hover {
background-color: #eee;
}
/* 滚动槽/外层轨道 */
::-webkit-scrollbar-track {
width: 5px;
height: 5px;
border-radius: 5px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: transparent;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
min-height: 5px;
min-width: 5px;
border-radius: 5px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar:hover {
background-color: #eee;
}
/* 滚动槽/外层轨道 */
::-webkit-scrollbar-track {
width: 5px;
height: 5px;
border-radius: 5px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: transparent;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
min-height: 5px;
min-width: 5px;
border-radius: 5px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
// 描述列表项垂直居中
.el-descriptions-item__container {
align-items: center;
}
\ No newline at end of file
<template>
<div>
<audio
@timeupdate="updateProgress"
controls
ref="audioRef"
style="display: none"
>
<source :src="fileurl" type="audio/mpeg" />
您的浏览器不支持音频播放
</audio>
<div class="audio-right">
<i
:class="
audioStatus !== 'pause' ? 'el-icon-video-play' : 'el-icon-video-pause'
"
@click="playAudio"
class="dialogAudioPlay"
></i>
<div class="progress-bar-bg" id="progressBarBg" v-dragto="setAudioIcon">
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="audio-time" style="min-height: 10px">
<span class="audio-length-current" id="audioCurTime">{{
audioStart
}}</span
>/
<span class="audio-length-total">{{ duration }}</span>
</div>
<div class="volume">
<div
@click.stop="
() => {
return false;
}
"
class="volume-progress"
v-show="audioHuds"
>
<div
class="volume-bar-bg"
id="volumeBarBg"
v-adjuster="handleShowMuteIcon"
>
<div class="volume-bar" id="volumeBar"></div>
</div>
</div>
<i
class="iconfont pl-1"
:class="audioIcon"
@click.stop="audioHuds = !audioHuds"
>
</i>
</div>
</div>
</div>
</template>
<script>
export default {
name: "NormalPlayer",
props: {
fileurl: {
trpe: String,
},
},
data() {
return {
audioStatus: "play",
audioStart: "0:00",
duration: "0:00",
audioVolume: 0.5,
audioHuds: false,
};
},
directives: {
dragto: {
inserted: function (el, binding, vnode) {
el.addEventListener(
"click",
(e) => {
let wdiv = document.getElementById("progressBarBg").clientWidth;
let audio = vnode.context.$refs.audioRef;
// 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
let ratemin = e.offsetX / wdiv;
let rate = ratemin * 100;
document.getElementById("progressBar").style.width = rate + "%";
audio.currentTime = audio.duration * ratemin;
audio.play();
binding.value();
},
false
);
},
},
adjuster: {
inserted: function (el, binding, vnode) {
el.addEventListener(
"click",
(e) => {
let hdiv = document.getElementById("volumeBarBg").clientHeight;
let audio = vnode.context.$refs.audioRef;
// 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
let ratemin = e.offsetY / hdiv;
let rate = ratemin * 100;
document.getElementById("volumeBar").style.height = rate + "%";
audio.volume = ratemin;
binding.value(rate / 100);
},
false
);
},
},
},
computed: {
audioIcon() {
if (this.audioHuds) {
return this.audioVolume < 0.01
? "checked icon-jingyin"
: "checked icon-shengyin";
} else {
return "icon-shengyin";
}
},
},
mounted() {
this.fetch();
},
methods: {
fetch() {
let that = this;
var myVid = this.$refs.audioRef;
myVid.loop = false;
// 监听音频播放完毕
myVid.addEventListener(
"ended",
function () {
that.audioStatus = "play"; // 显示播放icon
document.getElementById("progressBar").style.width = "0%"; // 进度条初始化
},
false
);
if (myVid != null) {
myVid.oncanplay = function () {
that.duration = that.transTime(myVid.duration); // 计算音频时长
};
myVid.volume = 0.5; // 设置音量50%
}
},
// 播放暂停控制
playAudio() {
let recordAudio = this.$refs.audioRef; // 获取audio元素
if (recordAudio.paused) {
recordAudio.play();
this.audioStatus = "pause";
} else {
recordAudio.pause();
this.audioStatus = "play";
}
},
// 更新进度条与当前播放时间
updateProgress(e) {
var value = e.target.currentTime / e.target.duration;
if (document.getElementById("progressBar")) {
document.getElementById("progressBar").style.width = value * 100 + "%";
if (e.target.currentTime === e.target.duration) {
this.audioStatus = "pause";
}
} else {
this.audioStatus = "pause";
}
this.audioStart = this.transTime(this.$refs.audioRef.currentTime);
},
/**
* 音频播放时间换算
* @param {number} value - 音频当前播放时间,单位秒
*/
transTime(time) {
var duration = parseInt(time);
var minute = parseInt(duration / 60);
var sec = (duration % 60) + "";
var isM0 = ":";
if (minute === 0) {
minute = "00";
} else if (minute < 10) {
minute = "0" + minute;
}
if (sec.length === 1) {
sec = "0" + sec;
}
return minute + isM0 + sec;
},
setAudioIcon() {
this.audioStatus = "pause";
},
handleShowMuteIcon(val) {
this.audioVolume = val;
},
},
};
</script>
<style lang="scss" scoped>
.volume {
position: relative;
.volume-progress {
position: absolute;
top: -150px;
width: 32px;
height: 140px;
background: #f6f6f6;
border-radius: 4px;
padding-top: 10px;
}
.volume-bar-bg {
margin: 0 auto;
width: 6px;
height: 120px;
background: #dcdcdc;
border-radius: 100px;
flex: 1;
position: relative;
transform: rotate(180deg);
cursor: pointer;
.volume-bar {
width: 6px;
height: 50%;
background: #56bf8b;
border-radius: 100px;
}
}
.checked {
color: #56bf8b;
}
}
.audio-right {
width: 100%;
height: 49px;
line-height: 49px;
background: #f5f5f9;
border-radius: 6px;
display: flex;
padding: 0 15px;
.dialogAudioPlay {
cursor: pointer;
color: #5c5e66;
display: flex;
align-items: center;
color: $deep-blue;
font-size: 38px;
}
.progress-bar-bg {
background-color: #fff;
flex: 1;
position: relative;
height: 10px;
top: 50%;
transform: translateY(-50%);
margin-top: -1px;
cursor: pointer;
margin: 0 10px;
}
.progress-bar {
background-color: $deep-blue;
width: 0%;
height: 10px;
border-radius: 5px;
}
.audio-time {
overflow: hidden;
font-size: 14px;
.audio-length-total {
float: right;
}
.audio-length-current {
float: left;
}
}
}
</style>
<template>
<audio
ref="audio"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
:src="url"
controls="controls"
></audio>
</template>
<script>
// 将整数转换成 时:分:秒的格式
function realFormatSecond(second) {
var secondType = typeof second;
if (secondType === "number" || secondType === "string") {
second = parseInt(second);
var hours = Math.floor(second / 3600);
second = second - hours * 3600;
var mimute = Math.floor(second / 60);
second = second - mimute * 60;
return (
hours + ":" + ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2)
);
} else {
return "0:00:00";
}
}
export default {
name: "AudioPlayer",
props: {
url: String,
},
data() {
return {
audio: {
// 该字段是音频是否处于播放状态的属性
playing: false,
// 音频当前播放时长
currentTime: 0,
// 音频最大播放时长
maxTime: 0,
},
};
},
methods: {
// 控制音频的播放与暂停
startPlayOrPause() {
return this.audio.playing ? this.pause() : this.play();
},
// 播放音频
play() {
this.$refs.audio.play();
},
// 暂停音频
pause() {
this.$refs.audio.pause();
},
// 当音频播放
onPlay() {
this.audio.playing = true;
},
// 当音频暂停
onPause() {
this.audio.playing = false;
},
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
onTimeupdate(res) {
this.audio.currentTime = res.target.currentTime;
},
// 当加载语音流元数据完成后,会触发该事件的回调函数
// 语音元数据主要是语音的长度之类的数据
onLoadedmetadata(res) {
console.log("loadedmetadata");
console.log(res);
this.audio.maxTime = parseInt(res.target.duration);
},
},
};
</script>
<style>
</style>
...@@ -248,7 +248,7 @@ export default { ...@@ -248,7 +248,7 @@ export default {
color: #5c5e66; color: #5c5e66;
display: flex; display: flex;
align-items: center; align-items: center;
color: $deep-blue; color: #2069c4;
font-size: 38px; font-size: 38px;
} }
.progress-bar-bg { .progress-bar-bg {
...@@ -263,7 +263,7 @@ export default { ...@@ -263,7 +263,7 @@ export default {
margin: 0 10px; margin: 0 10px;
} }
.progress-bar { .progress-bar {
background-color: $deep-blue; background-color: #2069c4;
width: 0%; width: 0%;
height: 10px; height: 10px;
border-radius: 5px; border-radius: 5px;
...@@ -281,3 +281,4 @@ export default { ...@@ -281,3 +281,4 @@ export default {
} }
} }
</style> </style>
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
:key="index" :key="index"
@click="handleClickItem(item)" @click="handleClickItem(item)"
> >
<!-- <img :src="item.pressUrl || item.faceImagePressUrl" alt="" /> -->
<div <div
class="img-container" class="img-container"
@click="handelPreviewImages(imgList, index)" @click="handelPreviewImages(imgList, index)"
...@@ -20,14 +19,6 @@ ...@@ -20,14 +19,6 @@
<slot name="img" :item="item"></slot> <slot name="img" :item="item"></slot>
</div> </div>
<slot name="info" :item="item" /> <slot name="info" :item="item" />
<!-- <div
class="enlarge"
@click="handelPreviewImages(imgList)"
v-if="needEnlarge"
>
<img src="@/assets/imgs/enlarge-s.png" alt="" />
<span>查看大图</span>
</div> -->
</swiper-slide> </swiper-slide>
<!--分页器。如果放置在swiper外面,需要自定义样式。--> <!--分页器。如果放置在swiper外面,需要自定义样式。-->
......
<template>
<div class="m-video">
<video-player
ref="videoPlayer"
@play="autoIncrement"
@timeupdate="onPlayerTimeupdate($event)"
@ready="playerReadied"
:playsinline="true"
:options="playerOptions"
>
</video-player>
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
default: "",
},
},
computed: {
player() {
return this.$refs.videoPlayer.player;
},
},
watch: {
src(newSrc) {
console.log("newSrc", newSrc);
this.toggle(newSrc);
},
},
data() {
return {
playerOptions: {
playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
autoplay: false, // 如果true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 导致视频一结束就重新开始。
preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: "zh-CN",
// aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如'16:9'或'4:3')
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
sources: [
{
// type: '',// 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
type: "video/mp4",
src: this.src, // url地址
},
],
// poster: '../../static/images/test.jpg', // 你的封面地址
// width: document.documentElement.clientWidth, // 播放器宽度
notSupportedMessage: "此视频暂无法播放,请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true,
durationDisplay: true,
remainingTimeDisplay: false,
fullscreenToggle: true, // 全屏按钮
playbackRateMenuButton: true,
chaptersButton: {},
audioTrackButton: true,
descriptionsButton: true,
},
controls: true,
},
};
},
methods: {
// ------------- 当播放时 ---------------
autoIncrement(player) {
/* this.$emit('autoIncrement', player)
this.player = player */
// player.currentTime(this.playTime)
},
// ----------- 当前播放进度更新时 ---------
onPlayerTimeupdate(player) {
// console.log('当前时间', player)
// this.playTime = player.cache_.currentTime // 获取当前播放进度(时间)
},
onPlayerCanplay() {
let player = this.$refs.videoPlayer.player;
player.play();
},
playerReadied(player) {},
toggle(newSrc) {
this.player.src(newSrc);
},
},
};
</script>
<style lang="scss" scoped>
.m-video {
height: 100%;
::v-deep .video-player {
height: 100%;
.video-js {
&:hover {
.vjs-big-play-button {
// background-color: #fff;
// color: $deep-blue;
}
}
video {
// object-fit: fill;
}
&.vjs-fluid {
height: 100% !important;
padding-top: 0;
}
.vjs-big-play-button {
left: 50%;
top: 50%;
width: 80px;
height: 80px;
border-radius: 50%;
transform: translate(-50%, -50%);
font-size: 50px;
color: #fff;
background-color: $deep-blue;
}
.vjs-control-bar {
.vjs-icon-custombutton {
font-family: VideoJS;
font-weight: normal;
font-style: normal;
}
.vjs-icon-custombutton:before {
content: "\f108";
font-size: 1.8em;
line-height: 1.67;
}
}
}
}
}
</style>
...@@ -97,12 +97,11 @@ export default { ...@@ -97,12 +97,11 @@ export default {
::v-deep .video-player { ::v-deep .video-player {
height: 100%; height: 100%;
.video-js { .video-js {
&:hover { &:hover {
.vjs-big-play-button { .vjs-big-play-button {
// background-color: #fff; // background-color: #fff;
// color: $deep-blue; // color: $deepBlue;
} }
} }
video { video {
......
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1698831219310" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2582" xmlns:xlink="http://www.w3.org/1999/xlink" width="80" height="80"><path d="M362.666667 213.333333h-85.333334c-36.266667 0-64 27.733333-64 64v85.333334c0 12.8 8.533333 21.333333 21.333334 21.333333s21.333333-8.533333 21.333333-21.333333v-85.333334c0-12.8 8.533333-21.333333 21.333333-21.333333h85.333334c12.8 0 21.333333-8.533333 21.333333-21.333333s-8.533333-21.333333-21.333333-21.333334zM362.666667 640h-85.333334c-12.8 0-21.333333-8.533333-21.333333-19.2V533.333333c0-12.8-8.533333-21.333333-21.333333-21.333333s-21.333333 8.533333-21.333334 21.333333v87.466667c0 34.133333 27.733333 61.866667 64 61.866667h85.333334c12.8 0 21.333333-8.533333 21.333333-21.333334s-8.533333-21.333333-21.333333-21.333333zM620.8 213.333333H533.333333c-12.8 0-21.333333 8.533333-21.333333 21.333334s8.533333 21.333333 21.333333 21.333333h87.466667c10.666667 0 19.2 8.533333 19.2 21.333333v85.333334c0 12.8 8.533333 21.333333 21.333333 21.333333s21.333333-8.533333 21.333334-21.333333v-85.333334c0-36.266667-27.733333-64-61.866667-64zM661.333333 512c-12.8 0-21.333333 8.533333-21.333333 21.333333v87.466667c0 10.666667-8.533333 19.2-19.2 19.2H533.333333c-12.8 0-21.333333 8.533333-21.333333 21.333333s8.533333 21.333333 21.333333 21.333334h87.466667c36.266667 0 61.866667-27.733333 61.866667-61.866667V533.333333c0-12.8-8.533333-21.333333-21.333334-21.333333z" p-id="2583"></path><path d="M953.6 923.733333L821.333333 789.333333c6.4-12.8 10.666667-27.733333 10.666667-42.666666V149.333333c0-46.933333-36.266667-85.333333-83.2-85.333333h-597.333333C104.533333 64 64 102.4 64 149.333333v597.333334c0 46.933333 40.533333 85.333333 87.466667 85.333333h597.333333c14.933333 0 29.866667-4.266667 42.666667-10.666667l132.266666 132.266667c4.266667 4.266667 10.666667 6.4 14.933334 6.4s10.666667-2.133333 14.933333-6.4c8.533333-8.533333 8.533333-21.333333 0-29.866667zM789.333333 746.666667c0 23.466667-17.066667 42.666667-40.533333 42.666666h-597.333333C128 789.333333 106.666667 770.133333 106.666667 746.666667V149.333333c0-23.466667 21.333333-42.666667 44.8-42.666666h597.333333c23.466667 0 40.533333 19.2 40.533333 42.666666v597.333334z" p-id="2584"></path></svg>
\ No newline at end of file
...@@ -7,26 +7,17 @@ import store from './store/index' ...@@ -7,26 +7,17 @@ import store from './store/index'
import ElementUI from 'element-ui'; import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; import 'element-ui/lib/theme-chalk/index.css';
import "@/assets/styles/index.scss"; //全局样式 import "@/assets/styles/index.scss"; //全局样式
import './icons' import './icons'
import animated from 'animate.css'; //不用进行Vue.use(animated) import animated from 'animate.css'; //不用进行Vue.use(animated)
import VideoPlayer from 'vue-video-player' import VideoPlayer from 'vue-video-player'
import 'video.js/dist/video-js.css' import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css' import 'vue-video-player/src/custom-theme.css'
import Viewer from 'v-viewer'//大图浏览,不使用elmentUI自带的imageViwer因为其不自带调整zoomRate import Viewer from 'v-viewer'//大图浏览,不使用elmentUI自带的imageViwer因为其不自带调整zoomRate
import 'viewerjs/dist/viewer.css' import 'viewerjs/dist/viewer.css'
import LImg from '@/components/LazyImg' import LImg from '@/components/LazyImg'
import {
getFullUrl
} from '@/utils/index'
import './permission' import './permission'
import '@/rem' import '@/rem'
import '@/utils/globalFunctions'
Vue.use(Viewer) Vue.use(Viewer)
Viewer.setDefaults({ Viewer.setDefaults({
...@@ -39,11 +30,9 @@ Vue.component('LImg', LImg) ...@@ -39,11 +30,9 @@ Vue.component('LImg', LImg)
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.use(ElementUI); Vue.use(ElementUI);
// 全局注册动画效果
// Vue.use(animated);
// 全局注册修改图片链接方法
Vue.prototype.$getFullUrl = getFullUrl
new Vue({ new Vue({
router, router,
......
// 此文件放置共用的一些方法,方便统一管理
import router from "@/router";
const bizCommon = {
openNewPage(path, query = {}) {
const newPage = router.resolve({
path,
query
});
window.open(newPage.href, "_blank");
}
}
export default bizCommon
\ No newline at end of file
// 本文件放置一些全局使用的方法,统一管理方便修改
import Vue from 'vue'
import {
getFullUrl
} from '@/utils/index'
import bizCommon from '@/utils/bizCommon'
Vue.prototype.$getFullUrl = getFullUrl //获取文件的完整链接
Vue.prototype.$bizCommon = bizCommon //业务层面的公共方法import {
\ No newline at end of file
...@@ -23,7 +23,6 @@ service.interceptors.request.use( ...@@ -23,7 +23,6 @@ service.interceptors.request.use(
config => { config => {
num++ num++
if (!loading) { if (!loading) {
let loadingTest = Loading.service
loading = Loading.service({ loading = Loading.service({
lock: true, lock: true,
text: '加载中,请稍后...', text: '加载中,请稍后...',
...@@ -54,7 +53,7 @@ service.interceptors.response.use( ...@@ -54,7 +53,7 @@ service.interceptors.response.use(
} }
const res = response.data const res = response.data
if (response.config.url === '/sys/getVerify') { if (response.config.url === '/sys/getVerify') {
// debugger
return res return res
} }
...@@ -67,55 +66,22 @@ service.interceptors.response.use( ...@@ -67,55 +66,22 @@ service.interceptors.response.use(
} }
res.data = arr res.data = arr
return res return res
} }
// debugger // debugger
// if the custom code is not 20000, it is judged as an error. // if the custom code is not 20000, it is judged as an error.
if (res.code !== 0) { if (res.code !== 0) {
// Message({
// message: res.msg || 'Error',
// type: 'error',
// duration: 5 * 1000
// })
// 401001l令牌过期;
messageup({ messageup({
type: 'error', type: 'error',
showClose: true, showClose: true,
message: res.msg || 'Error' message: res.msg || 'Error'
}) })
// if (res.code === 401001) { return Promise.reject(res.msg || 'Error')
// // MessageBox.confirm('登录令牌已过期,请重新登录', '确认退出', {
// // confirmButtonText: '重新登录',
// // cancelButtonText: '取消',
// // type: 'warning'
// // }).then(() => {
// // store.dispatch('user/resetToken').then(() => {
// // location.reload()
// // })
// // })
// store.dispatch('user/resetToken').then(() => {
// // window.location.reload()
// })
// }
// 单独处理登录接口,如果验证码输错
// if (response.config.url === 'sys/user/login' && res.code == 500002) {
// console.log(1111,res);
// return Promise.resolve(res)
// }
// console.log(response.config);
return Promise.reject(new Error(res.msg || 'Error'))
} else { } else {
return res return res
} }
}, },
error => { error => {
// console.log('err' + error) // for debug
// Message({
// message: error.msg || '网络连接错误,请稍后重试',
// type: 'error',
// duration: 5 * 1000
// })
messageup({ messageup({
type: 'error', type: 'error',
showClose: true, showClose: true,
......
差异被折叠。
<template>
<div>
<div class="common-title">文物音频</div>
<AudioPlayer
v-for="(v, i) in detail['audiosVo']"
:key="i"
:url="v.url"
ref="AudioPlayer"
/>
</div>
</template>
<script>
import AudioPlayer from "@/components/AudioPlayer";
export default {
components: {
AudioPlayer,
},
props: {
detail: {
type: Object,
default: () => ({}),
},
},
data() {
return {};
},
mounted() {},
methods: {},
};
</script>
<style scoped lang="scss">
@import "./common.scss";
audio {
width: 100%;
}
</style>
<template>
<div class="base-info">
<div class="wow animate__animated animate__fadeInLeft">
<div class="info-title">
<div class="name">{{ detail.name }}</div>
<div
class="view-3d"
title="查看文物3D模型"
v-if="has3d"
@click="handleTo3D"
>
<svg-icon icon-class="3d" class="icon"></svg-icon>
</div>
</div>
<div class="basic-info">
<div
class="body-item"
v-for="(item, index) in detailProps"
v-if="hasValue(item.prop)"
>
<span class="value" v-html="getPropValue(item.prop)"></span>
</div>
</div>
<!-- 文物简介 -->
<div v-if="detail.intro" class="intro" v-html="detail.intro"></div>
<ReaderOperations
class="reader"
:info="detail"
:sourceType="'biz_cultural_relic'"
color="#333"
selectColor="#333"
@reload="loadDetail"
/>
</div>
</div>
</template>
<script>
import ReaderOperations from "@/components/ReaderOperations";
import { detailProps } from "../config";
export default {
components: {
ReaderOperations,
},
props: {
detail: {
type: Object,
default: () => ({}),
},
},
computed: {
hasValue(prop) {
return (prop) => {
return this.detail[prop];
};
},
has3d() {
if (!this.detail) {
return;
}
return this.detail.file3dUrl || this.detail.url3d;
},
},
data() {
return {
detailProps,
};
},
methods: {
// 根据prop获取文物的基本信息
getPropValue(prop) {
return this.detail[prop] || "暂无";
},
loadDetail() {
this.$emit("loadDetail");
},
handleTo3D() {
const { file3dUrl, url3d } = this.detail;
if (file3dUrl) {
return;
}
if (url3d) {
const msg = this.$message.info("即将打开3D模型...");
setTimeout(() => {
msg.close();
window.open(this.detail.url3d, "_blank");
}, 1000);
return;
}
},
},
};
</script>
<style scoped lang="scss">
.base-info {
color: #333;
width: 100%;
padding: 20px;
.info-title {
display: flex;
align-items: center;
font-size: 46px;
font-family: "华文行楷";
font-weight: 600;
.name {
margin-right: 8px;
}
}
.basic-info {
color: #333;
position: relative;
font-weight: bold;
&::before {
content: "";
display: block;
height: calc(100% - 42px);
border-left: 1px dashed #333;
position: absolute;
top: 21px;
left: 0;
}
> div {
padding: 10px 0;
padding-left: 50px;
font-size: 18px;
position: relative;
&::before {
content: "";
display: block;
width: 40px;
border-top: 1px dashed #333;
position: absolute;
top: 50%;
left: 0;
}
}
}
.intro {
padding: 20px 0 40px;
line-height: 2;
max-height: 380px;
overflow: auto;
}
.reader {
margin-top: 20px;
}
}
</style>
.common-title {
font-size: 30px;
font-family: 'KaiTi';
margin-bottom: 30px;
display: flex;
justify-content: center;
}
\ No newline at end of file
<template>
<div class="imgs">
<div class="common-title">文物图片</div>
<swiper :options="swiperOption" ref="imgSwiper">
<swiper-slide v-for="(item, i) in detail.imagesVo" :key="i">
<div
title="点击查看大图"
class="img-container"
@click.stop="handelPreviewImages(detail.imagesVo, i)"
>
<img :src="$getFullUrl(item.middleUrl || item.url)" alt="" />
<div class="search" title="搜索类似图片">
<svg-icon
icon-class="search-pic"
@click.stop="handleSeachPic(item)"
></svg-icon>
</div>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
<div class="img-swiper-button-prev" slot="button-prev">
<i class="el-icon-arrow-left"></i>
</div>
<div class="img-swiper-button-next" slot="button-next">
<i class="el-icon-arrow-right"></i>
</div>
</div>
</template>
<script>
import { imgSwiperOption } from "../config";
import { swiper, swiperSlide } from "vue-awesome-swiper";
export default {
components: {
swiper,
swiperSlide,
"el-image-viewer": () =>
import("element-ui/packages/image/src/image-viewer"),
},
props: {
detail: {
type: Object,
default: () => ({}),
},
},
data() {
return {
swiperOption: imgSwiperOption,
};
},
mounted() {},
methods: {
handelPreviewImages(items, index) {
this.imgList = items.map((item) => this.$getFullUrl(item.url));
const $viewer = this.$viewerApi({
images: this.imgList,
options: {
initialViewIndex: index,
zoomRatio: 1.4,
},
});
},
handleSeachPic(item) {
const fileUrl = this.$getFullUrl(item.middleUrl || item.pressUrl);
const fileId = item.fileId;
const path = "/searchPic";
const query = {
fileId,
fileUrl,
};
this.$bizCommon.openNewPage(path, query);
},
},
};
</script>
<style scoped lang="scss">
@import "./common.scss";
.imgs {
position: relative;
height: calc(100vh - 340px);
.swiper-container {
width: 100%;
height: 100%;
.swiper-slide {
display: flex;
justify-content: center;
height: 100%;
}
.img-container {
width: 100%;
height: 100%;
background-color: #fff;
position: relative;
img {
height: 100%;
width: 100%;
object-fit: contain;
}
.search {
cursor: pointer;
position: absolute;
right: 20px;
top: 20px;
font-size: 20px;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: rgba($color: #000000, $alpha: 0.6);
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
}
}
.img-swiper-button-next,
.img-swiper-button-prev {
background-image: none;
border: 2px solid #c3c3c3;
background-color: rgba($deep-blue, 0.5);
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-weight: bolder;
font-size: 28px !important;
position: absolute;
top: 45%;
transform: translateY(-50%);
z-index: 99;
}
.img-swiper-button-next {
right: 0;
}
.img-swiper-button-prev {
left: 0;
}
}
</style>
<template>
<div class="literature">
<div class="common-title">相关文献</div>
<div class="lts-content">
<el-scrollbar style="height: 100%">
<div
class="lt-item"
v-for="(item, index) in detail.literatureVo"
:key="index"
@click="handleViewLt(item)"
>
<span class="lt-order">[{{ index + 1 }}]</span>
<span class="lt-authors" v-if="item.authors"
>{{ item.authors }}.</span
>
<span class="lt-name" v-if="item.name">{{ item.name }}.</span>
<span class="lt-source" v-if="item.source">{{ item.source }}.</span>
<span class="lt-date" v-if="item.date">{{ item.date }}</span>
</div>
</el-scrollbar>
</div>
</div>
</template>
<script>
export default {
props: {
detail: {
type: Object,
default: () => ({}),
},
},
data() {
return {};
},
mounted() {},
methods: {
// 预览关联文献
handleViewLt(item) {
if (item.files[0].url) {
previewFile(item.files[0].url, item.files[0].name);
} else {
this.$message.info("当前文献暂不支持在线浏览");
}
},
},
};
</script>
<style scoped lang="scss">
@import "./common.scss";
.literature {
width: 100%;
color: #333;
.lts-content {
height: 64vh;
overflow-y: auto;
overflow-x: hidden;
}
.lt-item {
border-bottom: 1px dashed #333;
padding: 10px 0;
cursor: pointer;
& > span {
padding: 0 4px;
}
}
}
</style>
<template>
<div class="relate">
<div class="common-title">相关文物</div>
<div class="recommend-type">
<div
v-for="(item, index) in tabs"
:key="index"
:class="{ active: item.key == currentTab.key, 'tab-item': true }"
@click="handleChangeTab(item)"
>
{{ item.label }}
</div>
</div>
<div class="recommend-obj">
<div class="recommend-obj-node" v-if="relateRelics.length > 0">
<div v-for="(item, index) in relateRelics" :key="index">
<div class="img-container" @click="handleViewCr(item)">
<img
:src="
$getFullUrl(item.faceImageMiddleUrl || item.faceImagePressUrl)
"
alt=""
/>
</div>
<div class="cr-name">{{ item.name }}</div>
</div>
</div>
<el-empty v-else description="暂无相关推荐,去看看其他的吧~"></el-empty>
</div>
</div>
</template>
<script>
export default {
props: {
relateRelics: {
type: Array,
default: () => [],
},
detail: {
type: Object,
default: () => ({}),
},
},
watch: {
detail(value) {
if (!value) {
return;
}
this.tabs = this.getTabs(value);
},
},
data() {
return {
typeTab: {
key: "type",
label: "同类别",
},
yearsTab: {
key: "years",
label: "同年代",
},
deptIdTab: {
key: "deptId",
label: "同馆藏",
},
currentTab: {},
tabs: [],
};
},
mounted() {},
methods: {
handleViewCr(item) {
const { crId } = item;
const path = "/culturalRelic/" + crId;
this.$bizCommon.openNewPage(path);
},
loadCrRecommend(key) {
this.$emit("loadCrRecommend", key);
},
getTabs(value) {
const tabs = [];
const { type, years, deptId } = value;
if (type) {
tabs.push(this.typeTab);
}
if (years) {
tabs.push(this.yearsTab);
}
if (deptId) {
tabs.push(this.deptIdTab);
}
this.currentTab = tabs[0];
return tabs;
},
handleChangeTab(tab) {
this.currentTab = tab;
this.loadCrRecommend(tab.key);
},
},
};
</script>
<style scoped lang="scss">
@import "./common.scss";
.relate {
width: 100%;
.recommend-type {
display: flex;
font-size: 18px;
color: #666;
justify-content: center;
.tab-item {
margin-right: 20px;
cursor: pointer;
}
.active {
color: $deep-blue;
font-weight: bold;
}
}
.recommend-obj {
width: 100%;
overflow: hidden;
.recommend-obj-node {
display: flex;
flex-wrap: wrap;
justify-content: center;
> div {
width: 40%;
padding: 20px;
}
}
.img-container {
width: 100%;
height: 220px;
display: flex;
justify-content: center;
&:hover {
cursor: pointer;
> img {
box-shadow: 0 10px 10px 0 rgba(0, 0, 0, 0.5);
}
}
> img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
transition: all 0.3s ease;
transform: scale(1);
}
}
.cr-name {
line-height: 32px;
text-align: center;
font-weight: 600;
font-family: "楷体";
color: #333;
font-size: 24px;
}
}
}
</style>
<template>
<!-- 文物视频 -->
<div class="video">
<div class="common-title">文物视频</div>
<div class="content">
<VideoPlayer
v-if="currentVideo"
:src="$getFullUrl(currentVideo.url)"
class="video-box"
></VideoPlayer>
<div class="video-names">
<div class="video-group">
<div
class="video-swiper-button-next swiper-button-white"
slot="button-next"
>
<i class="el-icon-arrow-right"></i>
</div>
<div
class="video-swiper-button-prev swiper-button-white"
slot="button-prev"
>
<i class="el-icon-arrow-left"></i>
</div>
<swiper
class="swiper gallery-thumbs"
ref="swiperThumbs"
:options="swiperOption"
>
<swiper-slide
:class="['name-item', isCurrentVideo(item) ? 'active' : '']"
v-for="(item, index) in detail.videosVo"
:key="index"
@click.native="handleChangeVideo(item)"
>
{{ getVideoName(item) }}
</swiper-slide>
<!--分页器。如果放置在swiper外面,需要自定义样式。-->
</swiper>
</div>
</div>
</div>
</div>
</template>
<script>
import VideoPlayer from "@/components/VideoPlayer";
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "swiper/dist/css/swiper.css";
import { videoSwiperOption } from "../config";
export default {
components: {
VideoPlayer,
swiper,
swiperSlide,
},
props: {
detail: {
type: Object,
default: () => ({}),
},
},
watch: {
detail(value) {
if (!value.videosVo) {
return;
}
this.currentVideo = value.videosVo[0];
},
},
computed: {
getVideoName(item) {
return (item) => {
return item.name.split(".")[0];
};
},
isCurrentVideo(item) {
return (item) => {
return item.fileId == this.currentVideo.fileId;
};
},
},
data() {
return {
currentVideo: {},
swiperOption: videoSwiperOption,
};
},
methods: {
handleChangeVideo(video) {
this.currentVideo = video;
},
},
};
</script>
<style scoped lang="scss">
@import "./common.scss";
.video {
height: 100%;
}
.content {
height: calc(100% - 50px);
.video-names {
height: 120px;
.video-group {
position: relative;
.name-item {
padding: 10px 30px;
background-color: #ccc;
border-radius: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: $deep-blue;
cursor: pointer;
}
.active {
background-color: $deep-blue;
color: #fff;
}
}
.swiper {
margin-top: 10px;
}
}
.video-box {
flex: 1;
height: calc(100vh - 420px);
}
}
.video-swiper-button-next,
.video-swiper-button-prev {
position: absolute;
top: 35%;
cursor: pointer;
}
.video-swiper-button-next {
right: -15px;
}
.video-swiper-button-prev {
left: -15px;
}
</style>
export const detailProps = [
{
prop: 'yearsLabel',
label: '年份'
},
{
prop: 'sourceWay',
label: '年份'
}, {
prop: 'typeLabel',
label: '类别'
},
{
prop: 'levelLabel',
label: '年代'
}, {
prop: 'textureTypeLabel',
label: '质地'
}, {
prop: 'detailSize',
label: '尺寸'
}, {
prop: 'deptName',
label: '馆藏单位'
}
]
export const tabs = [
{
name: "文物图片",
key: "imagesVo",
},
{
name: "相关视频",
key: "videosVo",
},
{
name: "相关音频",
key: "audiosVo",
},
{
name: "相关文物",
key: "relateRelics",
},
{
name: "相关文献",
key: "literatureVo",
},
]
export const imgSwiperOption = {
fadeEffect: {
crossFade: true,
},
// 显示分页
pagination: {
el: ".swiper-pagination",
clickable: true, //允许分页点击跳转
},
// 设置点击箭头
navigation: {
nextEl: ".img-swiper-button-next",
prevEl: ".img-swiper-button-prev",
},
}
export const videoSwiperOption = {
fadeEffect: {
crossFade: true,
},
// 显示分页
pagination: {
el: ".swiper-pagination",
clickable: true, //允许分页点击跳转
},
slidesPerView: 4,//'auto'
slidesPerGroup: 3,
spaceBetween: 20,
// 设置点击箭头
navigation: {
nextEl: ".video-swiper-button-next",
prevEl: ".video-swiper-button-prev",
},
}
\ No newline at end of file
...@@ -266,11 +266,8 @@ export default { ...@@ -266,11 +266,8 @@ export default {
handleClick(item) { handleClick(item) {
const { crId } = item; const { crId } = item;
const newPage = this.$router.resolve({ const path = "culturalRelic/" + crId;
path: "culturalRelic/" + crId, this.$bizCommon.openNewPage(path);
});
window.open(newPage.href, "_blank");
// this.$router.push(`culturalRelic/${crId}`);
}, },
handleClickThreeD() { handleClickThreeD() {
this.onlyShow3d = !this.onlyShow3d; this.onlyShow3d = !this.onlyShow3d;
......
<template> <template>
<div class="content"> <div class="content">
<!-- 展览图片 --> <!-- 展览图片 -->
<!-- <div class="content-item display-detail_imgs" ref="imgs">
<img
class="animate__animated animate__fadeInDownBig"
v-if="displayDetail.imagesVo && displayDetail.imagesVo.length > 0"
id="faceImage"
:src="$getFullUrl(displayDetail.imagesVo[0].pressUrl)"
/>
<img
id="faceImage"
v-else-if="displayDetail.faceImagePressUrl"
class="animate__animated animate__fadeInDownBig"
:src="displayDetail.faceImagePressUrl"
/>
</div> -->
<div class="breadcrumb"> <div class="breadcrumb">
<Breadcrumb :list="guideList" /> <Breadcrumb :list="guideList" />
</div> </div>
...@@ -214,23 +200,6 @@ ...@@ -214,23 +200,6 @@
<!-- <i class="el-icon-video-camera"></i> --> <!-- <i class="el-icon-video-camera"></i> -->
展览视频 展览视频
</div> </div>
<!-- <div class="video-names">
<swiper class="swiper video-swiper" :options="videoSwiperOption" ref="unitSwiper" v-if="currentVideo">
<swiper-slide :class="[
'slide-item',
item.fileId == currentVideo.fileId ? 'active' : '',
]" v-for="(item, index) in displayDetail.videosVo" :key="index"
@click.native="handleChangeCurrentVideo(item)">
{{ item.name.split(".")[0] }}
</swiper-slide>
</swiper>
<div class="swiper-button-prev video-swiper-button-prev" slot="button-prev">
<i class="el-icon-arrow-left"></i>
</div>
<div class="swiper-button-next video-swiper-button-next" slot="button-next">
<i class="el-icon-arrow-right"></i>
</div>
</div> -->
<div class="video-content"> <div class="video-content">
<div class="player"> <div class="player">
<video-player <video-player
......
<template> <template>
<div class="img-list"> <div class="img-list" :style="{ height: waterfallHeight }" ref="ImgList">
<vue-waterfall-easy <vue-waterfall-easy
v-if="imgList.length > 0 && contentWidth" v-if="imgList.length > 0 && contentWidth"
ref="waterfall" ref="waterfall"
...@@ -10,6 +10,11 @@ ...@@ -10,6 +10,11 @@
:gap="30" :gap="30"
@click="handleClickImg" @click="handleClickImg"
> >
<div class="img-info" slot-scope="props">
<div class="name">{{ props.value.sourceName }}</div>
<div class="year">{{ props.value.yearsLabel }}</div>
<div class="deptName">{{ props.value.deptName }}</div>
</div>
<div slot="waterfall-over" class="load-over">已加载完全部</div> <div slot="waterfall-over" class="load-over">已加载完全部</div>
</vue-waterfall-easy> </vue-waterfall-easy>
<el-empty v-else></el-empty> <el-empty v-else></el-empty>
...@@ -46,12 +51,8 @@ export default { ...@@ -46,12 +51,8 @@ export default {
}, },
data() { data() {
return { return {
current: 0,
size: 20,
total: 20,
hasMore: true,
// imgList,
contentWidth: 0, contentWidth: 0,
waterfallHeight: "120vh",
}; };
}, },
...@@ -59,15 +60,28 @@ export default { ...@@ -59,15 +60,28 @@ export default {
this.getContentWidth(); this.getContentWidth();
window.addEventListener("resize", () => { window.addEventListener("resize", () => {
this.getContentWidth(); this.getContentWidth();
console.log(123, this.contentWidth);
}); });
}, },
methods: { methods: {
getContentWidth() { getContentWidth() {
this.contentWidth = this.screenWidth * 0.76; this.contentWidth = this.screenWidth * 0.76;
}, },
handleClickImg(e) { // 给父组件调用的
console.log(e); getWaterfallHeight() {
const emptySpace = 300;
this.waterfallHeight = "100vh";
this.waterfallHeight =
this.$refs.ImgList.offsetHeight + emptySpace + "px";
},
handleClickImg(event, { index, value }) {
// 阻止a标签跳转
event.preventDefault();
// 只有当点击到图片时才进行操作
if (event.target.tagName.toLowerCase() == "img") {
const { sourceId } = value;
const path = "culturalRelic/" + sourceId;
this.$bizCommon.openNewPage(path);
}
}, },
}, },
}; };
...@@ -77,17 +91,8 @@ export default { ...@@ -77,17 +91,8 @@ export default {
$box-shadow: 0 2px 8px rgba(28, 31, 35, 0.03), $box-shadow: 0 2px 8px rgba(28, 31, 35, 0.03),
0 16px 48px 8px rgba(28, 31, 35, 0.08); 0 16px 48px 8px rgba(28, 31, 35, 0.08);
.img-list { .img-list {
height: calc(100vh);
display: flex; display: flex;
justify-content: center; justify-content: center;
// width: 80vw;
// ::v-deep .vue-waterfall-easy-container {
// width: 100%;
// }
// ::v-deep .vue-waterfall-easy {
// width: 100% !important;
// }
::v-deep .vue-waterfall-easy-container .vue-waterfall-easy a.img-inner-box { ::v-deep .vue-waterfall-easy-container .vue-waterfall-easy a.img-inner-box {
border-radius: none; border-radius: none;
box-shadow: none; box-shadow: none;
...@@ -103,19 +108,17 @@ $box-shadow: 0 2px 8px rgba(28, 31, 35, 0.03), ...@@ -103,19 +108,17 @@ $box-shadow: 0 2px 8px rgba(28, 31, 35, 0.03),
overflow: auto !important; overflow: auto !important;
} }
::v-deep .img-wraper {
img {
border-radius: 14px;
transition: all ease 0.3s;
box-shadow: $box-shadow;
&:hover {
// box-shadow: $box-shadow-deep;
}
}
}
.load-over { .load-over {
padding: 20px 0; padding: 20px 0;
} }
.img-info {
font-size: 14px;
color: #666;
.name {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
} }
</style> </style>
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
:class="['app-container', 'search-pic', showResult ? 'show-result' : '']" :class="['app-container', 'search-pic', showResult ? 'show-result' : '']"
> >
<div class="banner"> <div class="banner">
<div class="text"> <div class="text" v-if="!showResult">
<div class="title">以图搜图</div> <div class="title">以图搜图</div>
<div class="subtitle" v-if="!showResult"> <div class="subtitle">
以图搜图是一种方便快捷的搜索方式,它可以帮助您在海量的图片信息中快速找到您需要的图片。 以图搜图是一种方便快捷的搜索方式,它可以帮助您在海量的图片信息中快速找到您需要的图片。
<br /> <br />
通过上传或直接输入图片,以图搜图可以为您匹配相似的图片,或者根据图片内容找到相关的图片,让您可以更轻松地获取所需图片。 通过上传或直接输入图片,以图搜图可以为您匹配相似的图片,或者根据图片内容找到相关的图片,让您可以更轻松地获取所需图片。
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<div class="right-pic"></div> <div class="right-pic"></div>
</div> </div>
<div class="upload-wrapper"> <div class="upload-wrapper">
<div class="upload-bar" @click="handleClickUpload" v-loading="loading"> <div class="upload-bar" @click="handleClickUpload">
<div class="left-area" title="点击此处上传图片"> <div class="left-area" title="点击此处上传图片">
<div class="text">点击此处上传图片</div> <div class="text">点击此处上传图片</div>
<div class="camera"> <div class="camera">
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
:before-upload="handleBeforeUpload" :before-upload="handleBeforeUpload"
:show-file-list="false" :show-file-list="false"
:on-success="handleSuccess" :on-success="handleSuccess"
:disabled="loading"
> >
<el-button ref="uploadButton" class="upload-button">上传</el-button> <el-button ref="uploadButton" class="upload-button">上传</el-button>
</el-upload> </el-upload>
...@@ -41,16 +42,15 @@ ...@@ -41,16 +42,15 @@
<div class="img-container"> <div class="img-container">
<img :src="currentImg" alt="" /> <img :src="currentImg" alt="" />
</div> </div>
共计搜索结果{{ imgList.length }} 根据您上传的图片,为您推荐相似图片{{ imgList.length }}
</div> </div>
<ImgList v-if="showResult" :imgList="imgList" /> <ImgList v-if="showResult" :imgList="imgList" ref="List" />
<!-- <ImgList :imgList="imgList" /> -->
</div> </div>
</template> </template>
<script> <script>
import ImgList from "./components/imgList"; import ImgList from "./components/imgList";
import { searchImageByUpload } from "@/api/culturalRelic"; import { searchImageByUpload, searchImageByImg } from "@/api/culturalRelic";
export default { export default {
components: { components: {
ImgList, ImgList,
...@@ -64,7 +64,25 @@ export default { ...@@ -64,7 +64,25 @@ export default {
size: 20, size: 20,
}; };
}, },
mounted() {
const { fileId, fileUrl } = this.$route.query;
this.search(fileId, fileUrl);
},
methods: { methods: {
async search(fileId, fileUrl) {
if (!fileId || !fileUrl) {
return;
}
const params = {
size: this.size,
fileId,
};
const res = await searchImageByImg(params);
if (res.code == 0) {
this.currentImg = fileUrl;
this.imgList = res.data;
}
},
// 上传前钩子,处理文件类型 // 上传前钩子,处理文件类型
async handleBeforeUpload(file) { async handleBeforeUpload(file) {
let reg = /(?<=\.)[a-z]+$/g; let reg = /(?<=\.)[a-z]+$/g;
...@@ -74,20 +92,26 @@ export default { ...@@ -74,20 +92,26 @@ export default {
this.$message.warning("上传文件格式错误!"); this.$message.warning("上传文件格式错误!");
return; return;
} }
// mock上传过程
this.loading = true;
let formData = new FormData(); let formData = new FormData();
formData.append("file", file); formData.append("file", file);
formData.append("size", this.size); formData.append("size", this.size);
const start = this.$message.warning("正在上传..."); const loading = this.$loading({
lock: true,
text: "正在海量的图库中搜索...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
const res = await searchImageByUpload(formData); const res = await searchImageByUpload(formData);
if (res.code == 0) { if (res.code == 0) {
const length = res.data.length; const length = res.data.length;
this.$message.success(`上传成功并获得${length}条结果`); this.$message.success(`上传成功并获得${length}张相似图片`);
this.imgList = res.data; this.imgList = res.data;
this.showResult = true; this.showResult = true;
this.loading = false; loading.close();
this.showCurrentImg(file); this.showCurrentImg(file);
this.$nextTick(() => {
this.$refs["List"].getWaterfallHeight();
});
} }
}, },
showCurrentImg(file) { showCurrentImg(file) {
...@@ -96,7 +120,6 @@ export default { ...@@ -96,7 +120,6 @@ export default {
reader.readAsDataURL(file); reader.readAsDataURL(file);
reader.onload = function (e) { reader.onload = function (e) {
that.currentImg = this.result; //显示缩略图 that.currentImg = this.result; //显示缩略图
console.log(this.result);
}; };
}, },
// 上传成功之后的钩子 // 上传成功之后的钩子
...@@ -132,7 +155,7 @@ $transition-ease-03s: all ease 0.3s; ...@@ -132,7 +155,7 @@ $transition-ease-03s: all ease 0.3s;
} }
.show-result { .show-result {
.banner { .banner {
height: 200px; height: 40px;
.text { .text {
padding: 80px 12%; padding: 80px 12%;
} }
...@@ -147,7 +170,7 @@ $transition-ease-03s: all ease 0.3s; ...@@ -147,7 +170,7 @@ $transition-ease-03s: all ease 0.3s;
position: absolute; position: absolute;
left: -300px; left: -300px;
top: 100px; top: 100px;
height: 150%; height: 400px;
width: 700px; width: 700px;
background-size: contain; background-size: contain;
background-image: url("@/assets/imgs/line-draft/6.png"); background-image: url("@/assets/imgs/line-draft/6.png");
...@@ -158,7 +181,7 @@ $transition-ease-03s: all ease 0.3s; ...@@ -158,7 +181,7 @@ $transition-ease-03s: all ease 0.3s;
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 0; bottom: 0;
height: 80%; height: 200px;
width: 300px; width: 300px;
background-size: contain; background-size: contain;
background-image: url("@/assets/imgs/line-draft/3.png"); background-image: url("@/assets/imgs/line-draft/3.png");
...@@ -242,20 +265,23 @@ $transition-ease-03s: all ease 0.3s; ...@@ -242,20 +265,23 @@ $transition-ease-03s: all ease 0.3s;
.current-pic { .current-pic {
display: flex; display: flex;
justify-content: space-between; justify-content: flex-start;
align-items: center; align-items: center;
padding: 0 16%; padding: 20px 16%;
position: relative; position: relative;
z-index: 2; z-index: 2;
.img-container { .img-container {
display: flex; display: flex;
justify-content: flex-start;
padding: 20px 0;
position: relative; position: relative;
transition: all ease 0.3s; transition: all ease 0.3s;
margin-right: 16px;
width: 130px;
height: 130px;
background-color: #fff;
img { img {
width: 110px; width: 100%;
height: 110px; height: 100%;
object-fit: contain;
} }
} }
} }
...@@ -265,4 +291,8 @@ $transition-ease-03s: all ease 0.3s; ...@@ -265,4 +291,8 @@ $transition-ease-03s: all ease 0.3s;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
} }
::v-deep .el-loading-mask {
border-radius: 12px;
}
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论