tijiao
This commit is contained in:
parent
578b0f7b8d
commit
27534f574c
|
|
@ -23,6 +23,13 @@ export function participant(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
export function agreement(query) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/audit',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
}
|
||||
|
||||
//创建数据集
|
||||
export function add(data) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
//查询数据集
|
||||
export function list(query) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/list/all',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
export function creation(query) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/list/creation',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function participant(query) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/list/participant',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//创建数据集
|
||||
export function add(data) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 获取标注任务文件详情
|
||||
export function getAnnotationDetails(data) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getMyNoAnnotatedTask(data) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/getMyNoAuditedTask',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getMyAuditFiles(annotationStatus,taskId) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/getMyAuditFiles/'+annotationStatus+'/'+taskId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export function manualAnnotate(data) {
|
||||
return request({
|
||||
url: '/ai/annotationTask/manualAnnotate',
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
<template>
|
||||
<div class="label-studio-annotator">
|
||||
<div id="label-studio" class="annotation-container"></div>
|
||||
<div class="button-container">
|
||||
<button class="agree-button" @click="agreement(1)">同意</button>
|
||||
<button class="disagree-button" @click="showDisagreement = true">不同意</button>
|
||||
</div>
|
||||
<!-- 弹出层 -->
|
||||
<div v-if="showDisagreement" class="layui-layer">
|
||||
<div class="layui-layer-content">
|
||||
<h2><span STYLE="color: red">*</span>填写说明</h2>
|
||||
<textarea v-model="disagreementReason" placeholder="填写不同意的原因"></textarea>
|
||||
<div class="layui-layer-buttons">
|
||||
<button class="layui-btn layui-btn-primary" @click="sendDisagreement">提交</button>
|
||||
<button class="layui-btn layui-btn-danger" @click="closeDisagreementModal">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelStudio from 'label-studio';
|
||||
import 'label-studio/build/static/css/main.css';
|
||||
import {agreement, manualAnnotate } from '../../../../api/dataCenter/annotationTask';
|
||||
|
||||
export default {
|
||||
name: 'LabelStudioAnnotator',
|
||||
props: {
|
||||
fileUrl: { type: String, required: true },
|
||||
taskId: { type: Number, required: true },
|
||||
config: { type: String, required: true },
|
||||
id: { type: Number, required: true },
|
||||
itemIndex: { type: Number, required: true },
|
||||
annotations: {
|
||||
type: Array,
|
||||
default: () => [] // 默认值为空数组
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
index: {
|
||||
get() {
|
||||
return this.itemIndex;
|
||||
},
|
||||
set(value) {
|
||||
this.$parent.updateItemIndex(value); // 更新父组件的索引
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
labelStudio: null,
|
||||
annotationsList: [] ,
|
||||
showDisagreement: false, // 控制不同意说明弹出层的显示
|
||||
disagreementReason: '' // 存储不同意的原因
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
fileUrl: 'resetLabelStudio' // 当文件地址变化时,重置LabelStudio
|
||||
},
|
||||
mounted() {
|
||||
this.initLabelStudio(); // 组件挂载完成后初始化LabelStudio
|
||||
},
|
||||
methods: {
|
||||
// 关闭不同意说明弹出层
|
||||
closeDisagreementModal() {
|
||||
this.showDisagreement = false;
|
||||
this.disagreementReason = ''; // 清空原因
|
||||
},
|
||||
// 发送不同意原因到后台
|
||||
sendDisagreement() {
|
||||
if(this.disagreementReason === ""){
|
||||
this.$modal.msgSuccess('说明原因不能为空');
|
||||
return;
|
||||
}
|
||||
agreement({
|
||||
taskId: Number(this.taskId),
|
||||
fileId: Number(this.id),
|
||||
auditFailedReason: this.disagreementReason
|
||||
}).then(response => {
|
||||
this.$modal.msgSuccess('已提交不同意原因');
|
||||
this.closeDisagreementModal(); // 关闭弹出层
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
// 处理返回的标注数据
|
||||
getAnnotations() {
|
||||
return [{
|
||||
result: this.annotations.map(annotation => ({
|
||||
type: "rectanglelabels",
|
||||
from_name: "label",
|
||||
to_name: "image",
|
||||
value: {
|
||||
rectanglelabels: [annotation.label],
|
||||
x: annotation.x,
|
||||
y: annotation.y,
|
||||
width: annotation.width,
|
||||
height: annotation.height
|
||||
}
|
||||
}))
|
||||
}];
|
||||
},
|
||||
//不同意
|
||||
disagreement(){
|
||||
|
||||
},
|
||||
//同意的接口调用后台
|
||||
agreement(){
|
||||
agreement({
|
||||
taskId : Number(this.taskId),
|
||||
fileId : Number(this.id)
|
||||
}).then(response => {
|
||||
this.$modal.msgSuccess('已同意标注')
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
// 初始化 LabelStudio
|
||||
initLabelStudio() {
|
||||
this.cleanupLabelStudio(); // 清理之前的实例
|
||||
|
||||
const task = {
|
||||
id: this.id,
|
||||
data: { image: this.fileUrl },
|
||||
};
|
||||
if (this.annotations.length) {
|
||||
task.annotations = this.getAnnotations();
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
const labelStudioElement = document.getElementById('label-studio');
|
||||
if (!labelStudioElement) {
|
||||
console.error('Label Studio element not found');
|
||||
return;
|
||||
}
|
||||
|
||||
this.labelStudio = new LabelStudio('label-studio', {
|
||||
config: this.config,
|
||||
interfaces: [],
|
||||
user: { pk: 1, firstName: '标注者', lastName: '用户' },
|
||||
task,
|
||||
onLabelStudioLoad: (LS) => {
|
||||
if (!LS.annotationStore.selectedAnnotation) {
|
||||
const annotation = LS.annotationStore.addAnnotation({ userGenerate: true });
|
||||
LS.annotationStore.selectAnnotation(annotation.id);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
// 重置 LabelStudio
|
||||
resetLabelStudio() {
|
||||
this.cleanupLabelStudio();
|
||||
this.initLabelStudio(); // 重新初始化
|
||||
},
|
||||
// 清理 LabelStudio 实例
|
||||
cleanupLabelStudio() {
|
||||
if (this.labelStudio && this.labelStudio.destroy) {
|
||||
this.labelStudio.destroy();
|
||||
}
|
||||
const labelStudioElement = document.getElementById('label-studio');
|
||||
if (labelStudioElement) {
|
||||
labelStudioElement.innerHTML = ''; // 清空容器
|
||||
}
|
||||
this.labelStudio = null; // 置空实例
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.label-studio-annotator {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.annotation-container {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 500px; /* 设置最小高度 */
|
||||
}
|
||||
|
||||
.button-container {
|
||||
position: absolute;
|
||||
float: right;
|
||||
justify-content: center;
|
||||
margin-left: 28%;
|
||||
top: 53%;
|
||||
}
|
||||
|
||||
.agree-button, .disagree-button {
|
||||
padding: 10px 20px;
|
||||
margin: 0 5px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.agree-button {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.disagree-button {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 弹出层样式 */
|
||||
.layui-layer {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* 半透明背景 */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layui-layer-content {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
width: 400px; /* 宽度 */
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.layui-layer-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.layui-btn {
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layui-btn-primary {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.layui-btn-danger {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,9 +1,466 @@
|
|||
<template>
|
||||
<div class="div-main">
|
||||
<!-- 顶部区域 -->
|
||||
<div class="top-part">
|
||||
<div class="top-content">
|
||||
|
||||
<!-- 右侧选择框和设置按钮 -->
|
||||
<div class="top-content-right">
|
||||
<el-select
|
||||
v-model="taskId"
|
||||
placeholder="请选择审核任务"
|
||||
clearable
|
||||
class="select-task"
|
||||
@change="selectTask"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in taskList"
|
||||
:key="dict.taskId"
|
||||
:label="dict.taskName"
|
||||
:value="dict.taskId"
|
||||
|
||||
/>
|
||||
</el-select>
|
||||
<!-- <span class="settings-icon">
|
||||
<i class="el-icon-setting"></i>
|
||||
</span>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 底部区域 -->
|
||||
<div class="bottom-part">
|
||||
<div class="bottom-content">
|
||||
<div class="bottom-content-left">
|
||||
<div class="bottom-content-left-top">
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:class="{'is-selected': annotationType===0}"
|
||||
plain
|
||||
size="mini"
|
||||
@click="toggleSelected(0)"
|
||||
>全部
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:class="{'is-selected': annotationType===1}"
|
||||
plain
|
||||
size="mini"
|
||||
@click="toggleSelected(1)"
|
||||
>已审核
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:class="{'is-selected': annotationType===2}"
|
||||
plain
|
||||
size="mini"
|
||||
@click="toggleSelected(2)"
|
||||
>未审核
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:class="{'is-selected': annotationType===3}"
|
||||
plain
|
||||
size="mini"
|
||||
@click="toggleSelected(3)"
|
||||
>审核驳回
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-content-left-bottom">
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="(item, index) in images" :key="item.fileId" class="list-item">
|
||||
<div @click="setItem(item, index)">
|
||||
<input type="checkbox" :checked="item.fileAnnotationStatus==='1'" disabled>
|
||||
<span :class="{'highlighted': itemIndex === index}" style="font-size: 14px; margin-left: 5px;"
|
||||
>{{ item.fileName }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-content-center">
|
||||
<div>
|
||||
<custom-label-studio :annotations="annotationResult" :taskId="taskId" :item-index="itemIndex"
|
||||
:config="labelConfig" :id="task.id" :file-url="task.data.image"
|
||||
@update-itemIndex="updateItemIndex"
|
||||
></custom-label-studio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
<script>
|
||||
import customLabelStudio from './examLabelStudio.vue'
|
||||
import { getMyNoAnnotatedTask, getMyAuditFiles } from '../../../../api/dataCenter/examine'
|
||||
|
||||
export default {
|
||||
dicts: ['ai_annotate_type'],
|
||||
components: { customLabelStudio },
|
||||
data() {
|
||||
return {
|
||||
itemIndex: 0,
|
||||
annotationResult: [],
|
||||
item: {},
|
||||
taskList: [],
|
||||
task: {
|
||||
id: 0,
|
||||
data: {
|
||||
image: ''
|
||||
}
|
||||
},
|
||||
labelConfig: `
|
||||
<View>
|
||||
<Image name="image" value="$image"/>
|
||||
<RectangleLabels name="label" toName="image">
|
||||
</RectangleLabels>
|
||||
</View>
|
||||
`,
|
||||
taskId: undefined, // 当前选中的任务 ID
|
||||
leftIcons: [
|
||||
'el-icon-circle-plus-outline',
|
||||
'el-icon-remove-outline',
|
||||
'el-icon-search',
|
||||
'el-icon-search',
|
||||
'el-icon-search',
|
||||
'el-icon-search'
|
||||
], // 顶部左侧按钮的图标
|
||||
count: 600,
|
||||
annotationType: 0,
|
||||
images: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadTaskList(); // 初始化时加载任务列表
|
||||
},
|
||||
methods: {
|
||||
// 更新项的索引并切换任务数据
|
||||
updateItemIndex(val) {
|
||||
const item = this.images[val];
|
||||
this.images[val - 1].fileAnnotationStatus = '1';
|
||||
this.itemIndex = val;
|
||||
this.updateTaskData(item);
|
||||
},
|
||||
|
||||
// 加载未标注的任务列表
|
||||
loadTaskList() {
|
||||
getMyNoAnnotatedTask().then(res => {
|
||||
this.taskList = res.data;
|
||||
});
|
||||
},
|
||||
|
||||
// 根据任务ID选择审核并加载对应的文件
|
||||
selectTask(id) {
|
||||
this.resetImages();
|
||||
this.taskId = id;
|
||||
this.fetchImages();
|
||||
},
|
||||
|
||||
// 切换标注类型并加载任务文件
|
||||
toggleSelected(type) {
|
||||
if (this.annotationType === type) return;
|
||||
this.annotationType = type;
|
||||
this.resetImages();
|
||||
this.fetchImages();
|
||||
},
|
||||
|
||||
// 设置标注项,更新任务数据和标注结果
|
||||
setItem(item, index) {
|
||||
this.annotationResult = JSON.parse(item.annotationResult);
|
||||
this.itemIndex = index;
|
||||
this.updateTaskData(item);
|
||||
},
|
||||
|
||||
// 重置图像数据
|
||||
resetImages() {
|
||||
this.images = [];
|
||||
//this.annotationType = 0;
|
||||
},
|
||||
|
||||
// 获取当前任务ID审核注类型的图像数据
|
||||
fetchImages() {
|
||||
if (!this.taskId) return;
|
||||
getMyAuditFiles(this.annotationType, this.taskId).then(response => {
|
||||
//alert(JSON.stringify(response))
|
||||
this.itemIndex = 0;
|
||||
this.images = response.data;
|
||||
this.updateTaskData(
|
||||
this.images[this.itemIndex]);
|
||||
});
|
||||
},
|
||||
|
||||
// 更新任务的数据
|
||||
updateTaskData(item) {
|
||||
if (item !== undefined){
|
||||
this.task.data.image = `http://192.168.0.14:9090/bonus/${item.fileUrl}`;
|
||||
this.task.id = item.fileId;
|
||||
this.annotationResult = JSON.parse(item.annotationResult);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
/* 默认按钮样式 */
|
||||
.el-button {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 选中时的样式 */
|
||||
.el-button.is-selected {
|
||||
background-color: #007bff !important; /* 设置选中背景色 */
|
||||
border-color: #007bff !important; /* 设置选中边框色 */
|
||||
color: white !important; /* 设置字体颜色 */
|
||||
}
|
||||
|
||||
.div-main {
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
|
||||
/* 顶部样式 */
|
||||
.top-part {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
padding: 10px;
|
||||
|
||||
.top-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
|
||||
.top-content-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px; /* 按钮之间的间距 */
|
||||
}
|
||||
|
||||
.top-content-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.select-task {
|
||||
flex-shrink: 0; /* 防止选择框缩小 */
|
||||
}
|
||||
|
||||
.settings-icon {
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部样式 */
|
||||
.bottom-part {
|
||||
width: 100%;
|
||||
height: calc(100% - 60px);
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
|
||||
.bottom-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #dfe4ed;
|
||||
|
||||
.bottom-content-left,
|
||||
.bottom-content-center,
|
||||
.bottom-content-right {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom-content-left {
|
||||
width: 20%;
|
||||
|
||||
.bottom-content-left-bottom,
|
||||
.bottom-content-left-top {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.bottom-content-left-top {
|
||||
height: 50px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-content-left-bottom {
|
||||
height: calc(100% - 50px);
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
ul {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
list-style: none; /* 移除默认的点样式 */
|
||||
li {
|
||||
width: 100%;
|
||||
padding: 1px;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
div {
|
||||
height: 40px;
|
||||
padding-left: 2px;
|
||||
display: flex;
|
||||
cursor: pointer; /* 手势效果 */
|
||||
align-items: center;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
appearance: none; /* 隐藏默认复选框样式 */
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid #4d4e51;
|
||||
border-radius: 4px; /* 圆角方框 */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked::after {
|
||||
content: '✔'; /* 显示勾符号 */
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
background-color: rgb(64, 158, 255); /* 改变选中颜色 */
|
||||
border-color: rgb(64, 158, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 针对自定义滚动条样式 */
|
||||
ul::-webkit-scrollbar {
|
||||
cursor: default; /* 对滚动条自定义光标 */
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
ul::-webkit-scrollbar-thumb {
|
||||
background-color: #888;
|
||||
cursor: pointer; /* 手势效果 */
|
||||
}
|
||||
|
||||
ul::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-content-center {
|
||||
width: 80%;
|
||||
padding: 5px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-content-right {
|
||||
width: 20%;
|
||||
padding: 5px;
|
||||
|
||||
.bottom-content-right-center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.bottom-content-right-top {
|
||||
width: 100%;
|
||||
height: calc(50% - 25px);
|
||||
padding: 5px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-content-right-middle {
|
||||
width: 100%;
|
||||
height: calc(50% - 25px);
|
||||
padding: 5px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-content-right-bottom {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f7fa;
|
||||
border: 1px solid #dfe4ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
color: rgb(64, 158, 255); /* 选中项文本颜色 */
|
||||
font-size: 16px; /* 选中项字体大小 */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue