Merge branch 'main' of http://172.16.1.12/jiwanjun/ai-speech-build
This commit is contained in:
commit
62827114b6
|
|
@ -5,10 +5,12 @@
|
|||
-->
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
<speechControl></speechControl>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from "vue";
|
||||
import speechControl from "./view/components/speechControl.vue";
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -59,30 +59,16 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
watch(config, (newVal, oldVal) => {
|
||||
if (voiceControl.value && voiceControl.value.isListening) {
|
||||
voiceControl.value.stopListening();
|
||||
}
|
||||
initVoiceControl();
|
||||
});
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
|
||||
const config = {
|
||||
page: "Ecommerce Home",
|
||||
commands: [
|
||||
{
|
||||
command: "open_login",
|
||||
description: "打开登录弹窗或页面",
|
||||
command: "add_project",
|
||||
description: "新建项目",
|
||||
action: "click",
|
||||
selector: "#login-button, .login-btn, [data-login]",
|
||||
selector: "#ai-speech-add-project",
|
||||
params: [],
|
||||
},
|
||||
{
|
||||
|
|
@ -148,6 +134,20 @@ const config = {
|
|||
],
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
watch(config, (newVal, oldVal) => {
|
||||
if (voiceControl.value && voiceControl.value.isListening) {
|
||||
voiceControl.value.stopListening();
|
||||
}
|
||||
initVoiceControl();
|
||||
});
|
||||
|
||||
class VoiceControl {
|
||||
constructor(callback) {
|
||||
this.config = config;
|
||||
|
|
@ -232,6 +232,8 @@ class VoiceControl {
|
|||
const sequence = await this.queryDeepSeek(transcript);
|
||||
this.showStatus("指令执行完成", "success");
|
||||
|
||||
this.executeSequence(sequence);
|
||||
|
||||
if (sequence && sequence.sequence && sequence.sequence.length > 0) {
|
||||
this.callback(sequence.sequence);
|
||||
} else {
|
||||
|
|
@ -380,6 +382,92 @@ class VoiceControl {
|
|||
}
|
||||
}
|
||||
|
||||
async executeSequence(sequence) {
|
||||
for (const [index, instruction] of sequence.sequence.entries()) {
|
||||
try {
|
||||
await this.executeInstruction(instruction);
|
||||
|
||||
// 在指令之间添加延迟
|
||||
if (index < sequence.sequence.length - 1) {
|
||||
await this.delay(800);
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async executeInstruction(instruction) {
|
||||
const commandConfig = this.config.commands.find(
|
||||
(c) => c.command === instruction.command
|
||||
);
|
||||
|
||||
if (!commandConfig) {
|
||||
throw new Error(`未知指令: ${instruction.command}`);
|
||||
}
|
||||
|
||||
const element = document.querySelector(commandConfig.selector);
|
||||
if (!element) {
|
||||
throw new Error(`找不到元素: ${commandConfig.selector}`);
|
||||
}
|
||||
|
||||
// 滚动到元素可见
|
||||
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
|
||||
switch (commandConfig.action) {
|
||||
case "click":
|
||||
element.click();
|
||||
break;
|
||||
|
||||
case "input":
|
||||
const inputParam = commandConfig.params[0];
|
||||
if (instruction.params && instruction.params[inputParam.name]) {
|
||||
element.value = instruction.params[inputParam.name];
|
||||
element.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
}
|
||||
break;
|
||||
|
||||
case "navigate":
|
||||
if (instruction.params && instruction.params.product_url) {
|
||||
window.location.href = instruction.params.product_url;
|
||||
}
|
||||
break;
|
||||
|
||||
case "input_and_submit":
|
||||
if (instruction.params && instruction.params.keyword) {
|
||||
element.value = instruction.params.keyword;
|
||||
element.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
|
||||
// 尝试提交表单或点击相关按钮
|
||||
if (element.form) {
|
||||
element.form.submit();
|
||||
} else {
|
||||
// 查找提交按钮
|
||||
const submitBtn = document.querySelector(
|
||||
'#search-submit, [type="submit"]'
|
||||
);
|
||||
if (submitBtn) submitBtn.click();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`未知动作类型: ${commandConfig.action}`);
|
||||
}
|
||||
|
||||
// 添加视觉反馈
|
||||
this.highlightElement(element);
|
||||
}
|
||||
|
||||
highlightElement(element) {
|
||||
const originalStyle = element.style.boxShadow;
|
||||
// 模糊半径15px,扩散半径4px,透明度0.4(淡色微光)
|
||||
element.style.boxShadow = "0 0 12px 5px rgba(173, 216, 230, 0.6)";
|
||||
setTimeout(() => {
|
||||
element.style.boxShadow = originalStyle;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// UI 更新方法
|
||||
updateUI() {
|
||||
const voiceBtn = document.getElementById("voice-btn");
|
||||
|
|
@ -416,7 +504,7 @@ const voiceControl = ref(null);
|
|||
const action = ref([]);
|
||||
|
||||
const initVoiceControl = () => {
|
||||
voiceControl.value = new VoiceControl(this.callBackFun);
|
||||
voiceControl.value = new VoiceControl(callBackFun);
|
||||
};
|
||||
|
||||
const callBackFun = (data) => {
|
||||
|
|
@ -543,7 +631,7 @@ p {
|
|||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
color: #00000085;
|
||||
color: #ffffff85;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
|
|
@ -573,11 +661,11 @@ p {
|
|||
position: fixed;
|
||||
right: 160px;
|
||||
bottom: 30px;
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 12px 20px;
|
||||
border-radius: 12px;
|
||||
color: #00000080;
|
||||
color: #fff;
|
||||
max-width: 300px;
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
|
|
@ -594,6 +682,7 @@ p {
|
|||
.command-text {
|
||||
font-size: 16px;
|
||||
margin-bottom: 5px;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.command-action {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,34 @@
|
|||
<div class="app-container">
|
||||
<!-- 左侧导航栏 -->
|
||||
<aside class="sidebar">
|
||||
<!-- 用户信息 -->
|
||||
<div class="user-section">
|
||||
<div class="avatar"></div>
|
||||
<div>
|
||||
<div class="user-id">1735244688</div>
|
||||
<div class="user-label">用户ID</div>
|
||||
<div>
|
||||
<!-- 用户信息 -->
|
||||
<div class="user-section">
|
||||
<div class="avatar">
|
||||
<img src="./../assets/default-photo.jpeg" alt="" />
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-id">15586961409</div>
|
||||
<div class="user-label">网络公开版</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="split-line"></div>
|
||||
|
||||
<!-- 导航菜单 -->
|
||||
<nav class="nav-menu">
|
||||
<ul>
|
||||
<template v-for="(item, index) in menu">
|
||||
<li @click="selectMenu(item)" :class="item.active ? 'active' : ''">
|
||||
<el-icon :size="20">
|
||||
<component :is="item.icon" />
|
||||
</el-icon>
|
||||
<span>{{ item.name }}</span>
|
||||
</li>
|
||||
<div v-if="index == 2" class="split-line"></div>
|
||||
</template>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<!-- 导航菜单 -->
|
||||
|
|
@ -24,73 +45,92 @@
|
|||
</nav>
|
||||
|
||||
<!-- 广告卡片 -->
|
||||
<div class="ad-card">
|
||||
<div class="ad-img"></div>
|
||||
<div class="ad-title">大幅面优化 倾斜摄影卡顿</div>
|
||||
<button class="ad-btn">前往下载</button>
|
||||
</div>
|
||||
|
||||
<!-- 底部链接 -->
|
||||
<div class="footer-links">
|
||||
<a href="#">SDK文档</a>
|
||||
<a href="#">视频教程</a>
|
||||
<a href="#">人工客服</a>
|
||||
<a href="#">建议反馈</a>
|
||||
</div>
|
||||
<el-card header-class="card-header" body-class="card-body">
|
||||
<div class="card-content">
|
||||
<img src="./../assets/bg-1.png" style="width: 100%" />
|
||||
</div>
|
||||
</el-card>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main class="main-content">
|
||||
<!-- 顶部横幅 -->
|
||||
<section class="header-banner">
|
||||
<div class="banner-content">
|
||||
<h1>可视化</h1>
|
||||
<p>零代码数字孪生可视化平台</p>
|
||||
<div class="tag-group">
|
||||
<span>可视化大屏</span>
|
||||
<span>三维地图</span>
|
||||
<span>GIS</span>
|
||||
<span>数字孪生</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-carousel height="300px" motion-blur :interval="10000">
|
||||
<el-carousel-item v-for="item in 2" :key="item">
|
||||
<div class="banner-content">
|
||||
<div class="banner-content-info">
|
||||
<h1>可视化平台</h1>
|
||||
<p>零代码数字孪生可视化平台</p>
|
||||
<div class="tag-group">
|
||||
<span>可视化大屏</span>
|
||||
<span class="splitdot">·</span>
|
||||
<span>三维地图</span>
|
||||
<span class="splitdot">·</span>
|
||||
<span>GIS</span>
|
||||
<span class="splitdot">·</span>
|
||||
<span>数字孪生</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</section>
|
||||
|
||||
<!-- 项目操作栏 -->
|
||||
<section class="project-actions">
|
||||
<div class="action-buttons">
|
||||
<button @click="openNewProject">新建</button>
|
||||
<button>新建文件夹</button>
|
||||
<button>导入项目</button>
|
||||
</div>
|
||||
<div class="tab-group">
|
||||
<span class="active">本地项目</span>
|
||||
<span>云托管项目</span>
|
||||
<button id="ai-speech-add-project" @click="addProject">
|
||||
<el-icon :size="16">
|
||||
<DocumentAdd />
|
||||
</el-icon><span>新建</span>
|
||||
</button>
|
||||
<button>
|
||||
<el-icon :size="16">
|
||||
<FolderAdd />
|
||||
</el-icon><span>新建文件夹</span>
|
||||
</button>
|
||||
<button>
|
||||
<el-icon :size="16">
|
||||
<UploadFilled />
|
||||
</el-icon><span>导入项目</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="tabName" class="demo-tabs" @tab-click="handleClick" style="margin: 20px 0 8px 0">
|
||||
<el-tab-pane label="本地项目" name="local"></el-tab-pane>
|
||||
<el-tab-pane label="云托管项目" name="cloud"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="search-box">
|
||||
<input type="text" placeholder="搜索项目" />
|
||||
<el-input v-model="searchValue" style="width: 260px" class="responsive-input" placeholder="搜索项目"
|
||||
prefix-icon="Search" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 项目列表 -->
|
||||
<section class="project-list">
|
||||
<div class="project-card">
|
||||
<div class="card-img"></div>
|
||||
<div class="card-title">我的驾驶大屏示例</div>
|
||||
<div class="card-actions">
|
||||
<span>编辑</span>
|
||||
<span>复制</span>
|
||||
<span>删除</span>
|
||||
<div class="project-card" v-for="item in projects">
|
||||
<div class="project-item-info">
|
||||
<div class="card-title">{{ item.name }}</div>
|
||||
<div class="card-actions">
|
||||
<span><el-icon :size="18">
|
||||
<Promotion />
|
||||
</el-icon></span>
|
||||
<span><el-icon :size="18">
|
||||
<Delete />
|
||||
</el-icon></span>
|
||||
<span><el-icon :size="18">
|
||||
<Share />
|
||||
</el-icon></span>
|
||||
<span><el-icon>
|
||||
<MoreFilled />
|
||||
</el-icon></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="project-card">
|
||||
<div class="card-img"></div>
|
||||
<div class="card-title">我的智慧城市3D场景</div>
|
||||
<div class="card-actions">
|
||||
<span>编辑</span>
|
||||
<span>复制</span>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</main>
|
||||
<!-- 新建项目弹窗 -->
|
||||
|
|
@ -136,6 +176,15 @@ const menu = ref([
|
|||
active: false,
|
||||
},
|
||||
]);
|
||||
const searchValue = ref("");
|
||||
const tabName = ref("local");
|
||||
|
||||
const projects = ref([
|
||||
{
|
||||
name: '苏州站基础大屏示例',
|
||||
img: ''
|
||||
}
|
||||
])
|
||||
|
||||
const selectMenu = (data) => {
|
||||
menu.value.forEach((d) => {
|
||||
|
|
@ -147,10 +196,13 @@ const selectMenu = (data) => {
|
|||
});
|
||||
};
|
||||
|
||||
// 打开新建项目
|
||||
const openNewProject = () => {
|
||||
console.log("触发事件1", projectModal)
|
||||
dialogVisible.value = true
|
||||
const handleClick = (tab, event) => {
|
||||
console.log(tab, event);
|
||||
};
|
||||
|
||||
const addProject = () => {
|
||||
dialogVisible.value = true;
|
||||
console.log("正在点击新建按钮 ======> addProject ");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
@ -171,15 +223,16 @@ const openNewProject = () => {
|
|||
padding: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
background-color: #181818;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* 用户信息区 */
|
||||
.user-section {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
|
|
@ -187,17 +240,33 @@ const openNewProject = () => {
|
|||
height: 60px;
|
||||
background: #444;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 8px;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.user-id {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.user-label {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
color: #fff;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 2px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
/* 导航菜单 */
|
||||
|
|
@ -215,7 +284,7 @@ const openNewProject = () => {
|
|||
margin: 4px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
color: #ffffff99;
|
||||
color: #f8f8ff99;
|
||||
|
||||
.el-icon {
|
||||
margin-right: 6px;
|
||||
|
|
@ -228,7 +297,7 @@ const openNewProject = () => {
|
|||
}
|
||||
|
||||
.nav-menu li.active {
|
||||
background: rgb(5, 85, 158);
|
||||
background: #0078d4;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
|
@ -249,11 +318,16 @@ const openNewProject = () => {
|
|||
}
|
||||
|
||||
.ad-img {
|
||||
width: 80px;
|
||||
width: 80%;
|
||||
height: 80px;
|
||||
background: #444;
|
||||
border-radius: 4px;
|
||||
margin: 0 auto 12px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.ad-title {
|
||||
|
|
@ -305,33 +379,38 @@ const openNewProject = () => {
|
|||
height: 300px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
background-image: url("@/assets/banner.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-image: url("@/assets/banner.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
&-info {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
z-index: 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,10 +456,14 @@ const openNewProject = () => {
|
|||
|
||||
/* 项目操作栏 */
|
||||
.project-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.action-buttons button {
|
||||
|
|
@ -392,10 +475,16 @@ const openNewProject = () => {
|
|||
color: #fff;
|
||||
margin-right: 8px;
|
||||
transition: background 0.3s;
|
||||
display: flex;
|
||||
|
||||
.el-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons button:hover {
|
||||
background: #383838;
|
||||
background: #0078d4;
|
||||
border: 1px solid #0078d4;
|
||||
}
|
||||
|
||||
.tab-group span {
|
||||
|
|
@ -413,6 +502,12 @@ const openNewProject = () => {
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
background: rgb(26, 27, 29);
|
||||
border: 1px solid #444;
|
||||
|
|
@ -431,15 +526,19 @@ const openNewProject = () => {
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
padding: 16px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
width: 240px;
|
||||
width: 300px;
|
||||
height: 220px;
|
||||
background: rgb(26, 27, 29);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
padding: 18px;
|
||||
text-align: center;
|
||||
transition: transform 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
|
|
@ -448,7 +547,7 @@ const openNewProject = () => {
|
|||
|
||||
.card-img {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
height: 170px;
|
||||
background: #444;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 12px;
|
||||
|
|
@ -478,4 +577,59 @@ const openNewProject = () => {
|
|||
width: 160px;
|
||||
background: rgb(15, 15, 15);
|
||||
}
|
||||
.splitdot {
|
||||
margin: 0 20px !important;
|
||||
display: inline-block;
|
||||
}
|
||||
.split-line {
|
||||
height: 1px;
|
||||
width: 160px;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
margin: 30px auto;
|
||||
}
|
||||
.demo-tabs > .el-tabs__content {
|
||||
padding: 32px;
|
||||
color: #6b778c;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
::v-deep {
|
||||
.el-tabs__item {
|
||||
color: #ffffff80;
|
||||
}
|
||||
.el-tabs__item.is-active {
|
||||
color: #fff !important;
|
||||
}
|
||||
.el-tabs__nav-wrap::after {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.el-input__wrapper {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
box-shadow: none;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.card-body {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
.el-card {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
.card-content {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
height: 270px;
|
||||
img {
|
||||
height: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-item-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue