1121 lines
29 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-22 15:30:25
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-12-27 17:11:58
* @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue
* @Description: 大屏查看图片弹窗
-->
<template>
<div class="app">
<div class="left-list">
<div class="sidebar" ref="sidebar" @scroll="handleScroll">
<img
v-for="(item, index) in defectData"
:key="`${item.id}-${index}`"
:src="item.media[0].img"
:alt="'Image ' + (index + 1)"
@click="showImage(index)"
:class="{ selected: currentIndex === index }"
/>
</div>
</div>
<div class="main-content">
<!-- 搜索表单 -->
<div class="toolbar">
<el-form
:model="imgForm"
ref="imgForm"
size="small"
:inline="true"
label-width="5rem"
>
<el-row :gutter="24">
<el-col :span="7">
<el-form-item label="路段名称">
<el-select
v-model="imgForm.segmentId"
placeholder="请选择路段名称"
:popper-append-to-body="false"
filterable
clearable
>
<el-option
v-for="item in segmentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="病害类型">
<el-select
v-model="imgForm.defectType"
placeholder="请选择病害类型"
:popper-append-to-body="false"
clearable
>
<el-option
v-for="item in defectTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="公里桩">
<el-input
v-model="imgForm.stakeStart"
placeholder="起始公里桩"
style="width: 8rem"
clearable
/>
<span style="margin: 0 5px">-</span>
<el-input
v-model="imgForm.stakeEnd"
placeholder="终止公里桩"
style="width: 8rem"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="9">
<el-form-item label="病害长度">
<el-input-number
v-model="imgForm.minLen"
controls-position="right"
placeholder="最小长度"
:min="0"
></el-input-number>
<span style="margin: 0 5px">-</span>
<el-input-number
v-model="imgForm.maxLen"
controls-position="right"
placeholder="最大长度"
:min="0"
></el-input-number>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="病害面积">
<el-input-number
v-model="imgForm.minArea"
controls-position="right"
placeholder="最小面积"
:min="0"
></el-input-number>
<span style="margin: 0 5px">-</span>
<el-input-number
v-model="imgForm.maxArea"
controls-position="right"
placeholder="最大面积"
:min="0"
></el-input-number>
</el-form-item>
</el-col>
<el-col :span="6">
<el-button
type="primary"
class="btn-submit"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button class="btn-cancel" size="mini" @click="resetQuery"
>重置</el-button
>
</el-col>
</el-row>
</el-form>
</div>
<!-- 图片展示 -->
<div class="image-viewer">
<div class="rect-image">
<el-checkbox-group
v-model="checkedRect"
@change="handleCheckedRectChange"
>
<el-checkbox
class="image-info"
v-for="(item, index) in rectItem"
:label="item.id"
:key="`image-info-${index}`"
:style="{ color: colorList[index] }"
>采集时间:
{{ new Date(item.createdTime).toLocaleString() }} 起始桩号:
{{ item.stakeStart || "暂无数据" }} 终止桩号:
{{ item.stakeEnd || "暂无数据" }}
病害类型:
{{ item.defectTypeName || "暂无数据" }}
病害面积{{ item.targetArea }}平方米 病害长度{{
item.targetLen * 1 <= 0 ? "暂无数据" : `${item.targetLen}`
}}
</el-checkbox>
</el-checkbox-group>
</div>
<div class="image-container" ref="imageView">
<div
class="view-content"
ref="imageContainer"
@mousewheel="handleWeel"
:style="`width:${elWidth}rem;height:${elHeight}rem;transform: scale(${scale});transform-origin: top left`"
>
<img
:src="currentImage"
alt="Main Image"
ref="mainImage"
@load="updateRects"
/>
<div
class="rect-overlay"
v-for="(item, index) in checkedRectList"
:key="`rect-overlay-${index}`"
:style="getRectStyle(item.rectPosition, index)"
></div>
</div>
</div>
</div>
<!-- 小图展示 -->
<div class="thumbnail-row">
<div
class="thumbnail-image"
:style="{
justifyContent: currentThumbnails.length > 8 ? '' : 'center',
}"
>
<img
v-for="(mediaItem, index) in currentThumbnails"
:key="'thumb-' + index"
:src="mediaItem.img"
:alt="'Thumb ' + (index + 1)"
@click="showThumbnailImage(index)"
:class="{ selected: selectedThumbnail === index }"
/>
</div>
<div class="thumbnail-btn">
<el-button type="success" plain size="mini" @click="changeDefect(2)"
>是病害(Y)</el-button
>
<el-button type="warning" plain size="mini" @click="changeDefect(3)"
>不是病害(N)</el-button
>
</div>
</div>
</div>
</div>
</template>
<script>
import { getItemTypes } from "@/api/xj/screen/index";
import { listDefect, mergeDefect } from "@/api/xj/confirmation";
import throttle from "lodash/throttle";
import debounce from "lodash/debounce";
export default {
name: "ImgDialog",
props: {
imageItem: {
type: Object,
default: () => {},
},
searchForm: {
type: Object,
default: () => {},
},
segmentList: {
type: Array,
default: () => [],
},
},
data() {
return {
// 维度选择
labelCheck: "aim",
// 目标维度事件
aimList: [],
// 空间维度数据
ariaList: [],
// 左侧图片数据
defectData: [],
// 当前选择的index
currentIndex: null,
// 下方点击的index绑定
selectedThumbnail: 0,
// 选中框绑定
checkedRect: [],
// 顶端选中框数据
checkedRectList: [],
// 加载状态
loading: false,
// 表单绑定
imgForm: {
// 路段名称
segmentId: "",
// 病害类型
defectType: "",
// 起始公里桩
stakeStart: "",
// 终止公里桩
stakeEnd: "",
minLen: undefined,
maxLen: undefined,
minArea: undefined,
maxArea: undefined,
sortedFld: "",
sorted: "",
},
// 病害类型下拉数据
defectTypeList: [],
// 分页绑定
params: {
page: 1,
size: 10,
},
pageTip: 1,
// 图片病害位置红框信息
rectItem: [],
// 图片病害框的颜色
colorList: ["#FFFFFF", "#07E8E2", "#DD9F18", "#994EFF", "#08B4A6"],
// 父元素的宽-自适应值
initWidth: 0,
// 父元素的高-自适应值
initHeight: 0,
// 容器宽
elWidth: 0,
// 容器高
elHeight: 0,
// 放大比例
scale: 1,
};
},
computed: {
/**
* @description: 当前展示的图片url
* @param {*}
* @return {*}
*/
currentImage() {
const thumbnails = this.currentThumbnails;
return (
thumbnails[this.selectedThumbnail]?.img || thumbnails[0]?.img || ""
);
},
/**
* @description: 下方小列表数据
* @param {*}
* @return {*}
*/
currentThumbnails() {
return this.defectData[this.currentIndex]?.media || [];
},
},
watch: {
imageItem: {
handler(val) {
if (val) {
this.getMediaBySnapshotid(val);
}
},
deep: true,
immediate: true,
},
},
created() {
// this.getDefectType();
},
mounted() {},
mounted() {
this.initBodySize();
this.scrollInit();
window.addEventListener("keydown", throttle(this.handleKeydown, 100));
window.addEventListener("resize", this.updateRects);
},
methods: {
/**
* @description: 页面初始化
* @param {*}
* @return {*}
*/
initBodySize() {
this.initWidth = this.$refs.imageView.clientWidth; // 拿到父元素宽
this.initHeight = this.initWidth * ((1080 * 0.31) / (1920 - 1080 * 0.02)); // 根据宽计算高实现自适应
this.elWidth = this.initWidth * (100 / (1920 / 1.2));
this.elHeight = this.initHeight * (100 / (1080 / 2.15));
},
/**
* @description: 滚轮事件
* @param {*}
* @return {*}
*/
handleWeel(e) {
if (e.wheelDelta < 0) {
this.scale -= 0.25;
} else {
this.scale += 0.25;
}
if (this.scale >= 5.5) {
this.scale = 5.5;
return;
}
if (this.scale <= 1) {
this.scale = 1;
return;
}
this.elWidth = this.initWidth * (100 / (1920 / 1.2)) * this.zoom;
this.elHeight = this.initHeight * (100 / (1080 / 2)) * this.zoom;
// 调整滚动容器的尺寸
this.$nextTick(() => {
const container = this.$refs.imageContainer;
container.style.width = `${this.elWidth * this.scale}rem`;
container.style.height = `${this.elHeight * this.scale}rem`;
});
},
/**
* @description: 初始化鼠标拖动事件
* @param {*}
* @return {*}
*/
scrollInit() {
// 获取要绑定事件的元素
const nav = this.$refs.imageView;
let flag; // 鼠标按下
let downX; // 鼠标点击的x下标
let downY;
let scrollLeft; // 当前元素滚动条的偏移量
let scrollTop; // 当前元素滚动条的偏移量
nav.addEventListener("mousedown", function (event) {
flag = true;
downX = event.clientX; // 获取到点击的x下标
downY = event.clientY;
scrollLeft = this.scrollLeft; // 获取当前元素滚动条的偏移量
scrollTop = this.scrollTop;
});
nav.addEventListener("mousemove", function (event) {
if (flag) {
// 判断是否是鼠标按下滚动元素区域
let moveX = event.clientX; // 获取移动的x轴
let moveY = event.clientY;
let scrollX = moveX - downX; // 当前移动的x轴下标减去刚点击下去的x轴下标得到鼠标滑动距离
let scrollY = moveY - downY; // 当前移动的x轴下标减去刚点击下去的x轴下标得到鼠标滑动距离
this.scrollLeft = scrollLeft - scrollX; // 鼠标按下的滚动条偏移量减去当前鼠标的滑动距离
this.scrollTop = scrollTop - scrollY;
}
});
// 鼠标抬起停止拖动
nav.addEventListener("mouseup", function () {
flag = false;
});
// 鼠标离开元素停止拖动
nav.addEventListener("mouseleave", function (event) {
flag = false;
});
},
/**
* @description: 获取病害类型下拉数据
* @param {*}
* @return {*}
*/
getDefectType() {
getItemTypes({ classType: this.imgForm.classType }).then(
({ code, data }) => {
if (code === 200) {
this.defectTypeList = data;
}
}
);
},
/**
* @description: 根据传回来的快照id查图片详细数据
* @param {*}
* @return {*}
*/
getMediaBySnapshotid(val) {
this.currentIndex = val.index;
this.pageTip = val.params.page;
this.params = { ...val.params };
this.imgForm = {
...this.searchForm,
segmentId: this.searchForm.segmentName,
};
this.getDefectType();
this.getList();
setTimeout(() => {
if (this.pageTip > 1) {
this.loadMoreTopImages();
}
}, 500);
},
/**
* @description: 向下获取左侧列表事件
* @param {*}
* @return {*}
*/
getList() {
this.loading = true;
const data = {
lastId: this.defectData[this.defectData.length - 1]?.snapshotId || "",
...this.imgForm,
...this.params,
};
listDefect(data)
.then(({ code, rows }) => {
if (code === 200) {
this.defectData.push(...rows);
this.loading = false;
}
})
.finally(() => {
this.showImage(this.currentIndex);
this.loading = false;
});
},
/**
* @description: 向上获取列表数据
* @param {*}
* @return {*}
*/
getListTop() {
this.loading = true;
const data = {
...this.imgForm,
...this.params,
lastId: this.defectData[this.defectData.length - 1]?.snapshotId || "",
};
listDefect(data)
.then(({ code, rows }) => {
if (code === 200) {
this.defectData.unshift(...rows);
this.loading = false;
}
})
.finally(() => {
this.showImage(this.currentIndex);
this.loading = false;
});
},
/**
* @description: 点击搜索事件
* @param {*}
* @return {*}
*/
handleQuery() {
const stakeReg = /^K\d{4}\+\d{3}$/;
if (this.imgForm.stakeStart) {
if (stakeReg.test(this.imgForm.stakeStart)) {
this.defectData = [];
this.ariaList = [];
this.aimList = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
} else {
this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
}
} else if (this.imgForm.stakeEnd) {
if (stakeReg.test(this.imgForm.stakeEnd)) {
this.defectData = [];
this.ariaList = [];
this.aimList = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
} else {
this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
}
} else {
this.defectData = [];
this.ariaList = [];
this.aimList = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
}
},
/**
* @description: 重置事件
* @param {*}
* @return {*}
*/
resetQuery() {
this.defectData = [];
this.ariaList = [];
this.aimList = [];
this.imgForm = {
segmentId: "",
defectType: "",
stakeStart: "",
stakeEnd: "",
minLen: undefined,
maxLen: undefined,
minArea: undefined,
maxArea: undefined,
sortedFld: "",
sorted: "",
};
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
},
/**
* @description: 左侧点击图片事件
* @param {*}
* @return {*}
*/
showImage(index) {
this.currentIndex = index;
this.scale = 1;
const indexInfo = this.defectData[this.currentIndex]?.media.length - 1;
this.selectedThumbnail = indexInfo; // Reset to the first thumbnail when changing the main item
this.$nextTick(() => {
this.scrollToCurrentImage();
this.updateRects();
});
},
/**
* @description: 点击下方小列表
* @param {*}
* @return {*}
*/
showThumbnailImage(index) {
this.selectedThumbnail = index;
this.updateRects();
},
/**
* @description: 使图片展示在父级容器可视区域
* @param {*}
* @return {*}
*/
scrollToCurrentImage: debounce(function () {
if (this.$refs.sidebar) {
const sidebarImages = this.$refs.sidebar.querySelectorAll("img");
const currentImageElement = sidebarImages[this.currentIndex];
if (currentImageElement) {
currentImageElement.scrollIntoView({
behavior: "smooth",
block: "center",
});
}
}
}, 200),
/**
* @description: 滚动触发事件
* @param {*}
* @return {*}
*/
handleScroll() {
const sidebar = this.$refs.sidebar;
// 滚动到顶加载数据
if (sidebar.scrollTop < 2 && this.pageTip > 1 && !this.loading) {
this.loadMoreTopImages();
}
// 滚动到底加载数据
// 滚动高度+容器高度 滚动区域高度
if (
sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 &&
!this.loading
) {
this.loadMoreBottomImages();
}
// if (this.currentIndex === this.defectData.length - 1) {
// this.loadMoreBottomImages();
// }
},
/**
* @description: 向下加载更多图片方法
* @param {*}
* @return {*}
*/
loadMoreBottomImages() {
this.params.page += 1;
this.getList();
},
/**
* @description: 向上加载更多图片
* @param {*}
* @return {*}
*/
loadMoreTopImages() {
this.pageTip -= 1;
this.params.page -= 1;
this.currentIndex += this.params.size;
this.getListTop();
},
/**
* @description: 键盘事件
* @param {*}
* @return {*}
*/
handleKeydown(event) {
if (event.key === "ArrowUp") {
event.preventDefault();
if (this.currentIndex > 0) {
this.currentIndex--;
this.scale = 1;
const index = this.defectData[this.currentIndex].media.length - 1;
this.selectedThumbnail = index; // Reset when changing main images via keyboard
this.scrollToCurrentImage();
this.updateRects();
}
} else if (event.key === "ArrowDown") {
event.preventDefault();
if (this.currentIndex < this.defectData.length - 1) {
this.currentIndex === this.defectData.length - 1
? this.currentIndex
: this.currentIndex++;
this.scale = 1;
const index = this.defectData[this.currentIndex].media.length - 1;
this.selectedThumbnail = index; // Reset when changing main images via keyboard
this.scrollToCurrentImage();
this.updateRects();
} else {
this.loadMoreBottomImages();
}
} else if (event.keyCode === 89) {
// 确认病害
this.changeDefect(2);
} else if (event.keyCode === 78) {
// 不是病害
this.changeDefect(3);
}
},
/**
* @description: 选择框修改事件
* @param {*} val
* @return {*}
*/
handleCheckedRectChange(val) {
this.checkedRectList = this.rectItem.filter((item) => {
return val.includes(item.id);
});
},
/**
* @description: 图片位置信息获取
* @param {*} val
* @return {*}
*/
updateRects() {
this.rectItem = [];
if (
this.defectData.length > 0 &&
this.defectData.length > this.currentIndex
) {
if (
this.selectedThumbnail >
this.defectData[this.currentIndex]?.media.length - 1
) {
this.selectedThumbnail =
this.defectData[this.currentIndex]?.media.length - 1;
}
const array = this.defectData[this.currentIndex]?.media.map((item) => {
return {
...item,
createdTime: this.defectData[this.currentIndex].createdTime,
stakeEnd: this.defectData[this.currentIndex].stakeEnd,
stakeStart: this.defectData[this.currentIndex].stakeStart,
defectTypeName: this.defectData[this.currentIndex].defectTypeName,
targetArea: this.defectData[this.currentIndex].targetArea,
targetLen: this.defectData[this.currentIndex].targetLen,
rectPosition: item.rect?.split(",").map(Number),
};
});
this.rectItem = [array[this.selectedThumbnail]];
this.checkedRectList = this.rectItem;
this.checkedRect = [array[this.selectedThumbnail].id];
}
},
/**
* @description: 图片红框位置
* @param {*}
* @return {*}
*/
getRectStyle([left, top, width, height], index) {
const image = this.$refs.mainImage;
const container = this.$refs.imageContainer;
if (!image || !container) return {};
const scaleX = container.clientWidth / image.naturalWidth;
const scaleY = container.clientHeight / image.naturalHeight;
const scale = Math.min(scaleX, scaleY);
const renderedWidth = image.naturalWidth * scale;
const renderedHeight = image.naturalHeight * scale;
const offsetX = (container.clientWidth - renderedWidth) / 2;
const offsetY = (container.clientHeight - renderedHeight) / 2;
return {
position: "absolute",
left: `${left * scale + offsetX}px`,
top: `${top * scale + offsetY}px`,
width: `${width * scale}px`,
height: `${height * scale}px`,
border: "2px solid #FF0000",
boxSizing: "border-box",
border: `2px solid ${this.colorList[index]}`,
};
},
/**
* @description: 是病害/不是病害点击事件
* @param {*}
* @return {*}
*/
changeDefect(value) {
if (this.defectData.length > 0) {
mergeDefect({
status: value,
snapShotIds: [this.defectData[this.currentIndex].snapshotId],
})
.then(({ code, msg }) => {
if (code === 200) {
this.defectData.splice(this.currentIndex, 1);
// this.currentIndex + 1;
this.$modal.msgSuccess("修改成功");
} else {
this.$modal.msgWarning(msg);
}
})
.finally(() => {
this.showImage(this.currentIndex);
if (this.defectData.length < 4) {
this.defectData.splice(
(this.params.page - 1) * 10,
this.defectData.length - 1
);
this.getList();
}
});
}
},
},
beforeDestroy() {
window.removeEventListener("keydown", this.handleKeydown);
window.removeEventListener("resize", this.updateRects);
},
};
</script>
<style lang="scss" scoped>
.app {
width: 100%;
// height: 54rem;
height: calc(100vh - 4rem);
display: flex;
flex-direction: row;
background-color: #2e3a46;
}
.left-list {
width: 16rem;
height: 100%;
.sidebar {
width: 15.5rem;
height: calc(100% - 0.5rem);
// height: 815px;
background-color: #1f292e;
padding: 10px;
overflow-y: auto;
}
.sidebar::-webkit-scrollbar {
width: 8px;
}
.sidebar::-webkit-scrollbar-track {
background: #2e3a46;
border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb {
background: #444c51;
border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: #00aaff;
}
.sidebar img {
width: 100%;
margin-bottom: 5px;
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.sidebar img.selected {
border: 3px solid #00aaff;
transform: scale(1.05);
}
}
.main-content {
width: calc(100% - 250px);
height: 100%;
background-color: #1b2126;
padding: 10px;
display: flex;
flex-direction: column;
}
.toolbar {
width: 100%;
height: 7rem;
display: flex;
align-items: center;
background-color: #333c42;
padding: 5px;
border-bottom: 1px solid #333c42;
::v-deep .el-form {
width: 100%;
.el-form-item--small .el-form-item__label {
color: #ffffff;
}
.el-select {
width: 100%;
.el-input--small .el-input__inner {
color: #ffffff;
background-color: #333c42;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.el-select-dropdown__item {
color: #ffffff;
}
.el-select-dropdown__item:hover {
background-color: #2b4c7e;
}
.el-select-dropdown__item.selected {
background-color: #2b4c7e;
}
.el-select-dropdown__item.hover {
background-color: #2b4c7e;
}
}
.el-select-dropdown__list {
background-color: #333c42;
}
}
}
}
}
.el-input--small .el-input__inner {
color: #ffffff;
background-color: #333c42;
}
.el-input-number {
.el-input-number__decrease,
.el-input-number__increase {
background: transparent;
color: #ffffff;
}
}
}
}
.image-container {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
}
// 画框样式
.rect-overlay {
position: absolute;
pointer-events: none;
}
.image-viewer {
// height: 43rem;
height: calc(100% - 12rem);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #22272b;
position: relative;
// 图片信息
.rect-image {
width: 90%;
position: absolute;
top: 0;
z-index: 1;
}
// 修改选择框样式
::v-deep .image-info {
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
.el-checkbox__input.is-checked + .el-checkbox__label {
color: inherit;
font-size: 0.8rem;
line-height: 0.8rem;
}
.el-checkbox__label {
color: inherit;
font-size: 0.8rem;
line-height: 0.8rem;
}
}
.view-content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
position: relative;
}
.view-content img {
max-width: 100%;
max-height: 100%;
pointer-events: none;
object-fit: contain;
}
}
// 小图样式
.thumbnail-row {
width: 100%;
height: 5rem;
display: flex;
.thumbnail-image {
width: 87%;
height: 100%;
display: flex;
// justify-content: center;
overflow-x: auto;
padding: 0.4rem;
background-color: #333c42;
gap: 5px;
}
.thumbnail-image img {
width: 100px;
height: 60px;
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.thumbnail-image img.selected {
border: 3px solid #00aaff;
}
.thumbnail-btn {
width: 13%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
padding: 0.4rem;
background-color: #333c42;
> button {
width: 6rem;
margin: 0;
}
}
}
// 按钮样式
.btn-submit {
background-color: transparent;
background-image: url("~@/assets/screen/index/btn-submit.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
border-color: transparent;
color: #ffffff;
&:active {
color: #0d9ee2;
}
}
.btn-cancel {
background-color: transparent;
background-image: url("~@/assets/screen/index/btn-cancel.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
border-color: transparent;
color: #ffffff;
&:active {
color: #0d9ee2;
}
}
</style>