fix/弹窗样式优化,弹窗添加基础交互,弹窗联动语音控制

This commit is contained in:
季万俊 2025-08-27 10:59:05 +08:00
parent b65fbea138
commit b593ca70ae
3 changed files with 166 additions and 57 deletions

View File

@ -1,7 +1,7 @@
<!-- 新建项目弹窗 --> <!-- 新建项目弹窗 -->
<style scoped> <style lang="less" scoped>
.Main :deep(.el-dialog) { .Main :deep(.el-dialog) {
background: #535050 !important; background: rgba(38, 39, 42, 1) !important;
padding: 0px !important; padding: 0px !important;
} }
@ -90,7 +90,7 @@
.my-header { .my-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
background-color: #8f8888; background-color: rgba(30, 30, 30, 30);
align-items: center; align-items: center;
padding: 10px; padding: 10px;
} }
@ -107,14 +107,15 @@
padding: 10px; padding: 10px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; min-height: 500px;
}
.CenterBox {
flex: 1;
} }
.LeftBox, .LeftBox,
.CenterBox, .CenterBox,
.RightBox { .RightBox {
flex: 1; height: 100%;
height: 400px;
margin: 0 5px; margin: 0 5px;
border-radius: 4px; border-radius: 4px;
overflow: auto; overflow: auto;
@ -129,12 +130,14 @@
} }
.LeftItem { .LeftItem {
height: 100px; height: 150px;
width: 300px;
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
margin-bottom: 10px; margin-bottom: 10px;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
border-radius: 4px;
} }
.LeftItem span { .LeftItem span {
@ -154,31 +157,51 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 10px; gap: 10px;
padding-top: 10px;
box-sizing: border-box;
} }
.CenterItem { .CenterItem {
width: calc(33.333% - 7px); width: calc(33.333% - 7px);
height: 90px; height: 150px;
border-radius: 4px; border-radius: 4px;
overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
background: #9e9898; background: rgb(30, 30, 30);
color: #fff; color: #fff;
} }
.empty-folders {
width: 100%;
height: 120px;
text-align: center;
line-height: 120px;
background: rgb(46, 47, 51);
margin-bottom: 4px;
padding-top: 30px;
box-sizing: border-box;
color: #ffffff85;
&.sp {
height: 180px;
width: 290px;
border-radius: 8px;
padding-top: 50px;
margin-bottom: 15px;
}
}
.CenterItem:hover { .CenterItem:hover {
background: #9e9898; background: #0078d4;
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
} }
.CenterItem img { .CenterItem img {
width: 100%; width: 100%;
height: 60px; height: 120px;
object-fit: cover; object-fit: cover;
border-radius: 4px; border-radius: 4px 4px 0 0;
margin-bottom: 8px;
} }
.CenterItem span { .CenterItem span {
@ -191,14 +214,17 @@
} }
.RightBox { .RightBox {
padding-top: 10px; width: 290px;
padding-top: 65px;
box-sizing: border-box; box-sizing: border-box;
color: #fff; color: #f5f5f5;
} }
.RightBox img { .RightBox img {
width: 100%; width: 100%;
height: 100px; height: 180px;
border-radius: 8px;
} }
.RightBox h2 { .RightBox h2 {
@ -226,7 +252,26 @@
margin-top: 10px; margin-top: 10px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.close-btn {
background: transparent;
color: #fff;
border: 1px solid #ffffff90 !important;
}
}
.is-select {
border: 1px solid #0078d4;
position: relative;
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background: #0078d420;
}
} }
</style> </style>
@ -240,7 +285,7 @@
</template> </template>
<div class="contentBox"> <div class="contentBox">
<div class="LeftBox"> <div class="LeftBox">
<div class="LeftItem" v-for="value in projectClassList" <div class="LeftItem" @click="selectType(value)" :class="value.type == selectTypeValue ? 'is-select' : ''" v-for="value in projectClassList"
:style="{ backgroundImage: `url(${value.img})` }"> :style="{ backgroundImage: `url(${value.img})` }">
<span>{{ value.name }}</span> <span>{{ value.name }}</span>
</div> </div>
@ -250,8 +295,11 @@
<el-tabs v-model="activeName" class="demo-tabs"> <el-tabs v-model="activeName" class="demo-tabs">
<el-tab-pane label="全部" name="ALL"> <el-tab-pane label="全部" name="ALL">
<div class="CenterBottom"> <div class="CenterBottom">
<div class="CenterItem" v-for="value in largeScreenClassList"> <div class="CenterItem" @click="selectTemplate(value)" :class="value.type == selectTemplateValue.type ? 'is-select' : ''" v-for="value in largeScreenClassList">
<img :src="value.img" alt=""> <img v-if="value.img" :src="value.img" alt="">
<div class="empty-folders" v-else>
<el-icon :size="50"><Files /></el-icon>
</div>
<span>{{ value.name }}</span> <span>{{ value.name }}</span>
</div> </div>
</div> </div>
@ -261,17 +309,20 @@
</div> </div>
</div> </div>
<div class="RightBox"> <div class="RightBox">
<img src="/src/assets/images/sjdp1.png" alt=""> <img v-if="selectTemplateValue.img" :src="selectTemplateValue.img" alt="">
<h2>基础大屏示列</h2> <div class="empty-folders sp" v-else>
<p>包含所有2D基础元素的大屏示列</p> <el-icon :size="50"><Files /></el-icon>
<div class="FileInfo">文件信息大小3MB</div> </div>
<h2>{{ selectTemplateValue.name }}</h2>
<p>{{ selectTemplateValue.description }}</p>
<div class="FileInfo">项目信息大小{{ selectTemplateValue.size }}MB</div>
<div class="NameBox"> <div class="NameBox">
<h4>项目名称</h4> <h4>项目名称</h4>
<el-input placeholder="请输入名称" /> <el-input v-model="projectName" id="ai-speech-project-name" placeholder="请输入名称" />
</div> </div>
<div class="FootBtn"> <div class="FootBtn">
<el-button @click="handleClose">取消</el-button> <el-button class="close-btn" @click="handleClose">取消</el-button>
<el-button type="primary">创建项目</el-button> <el-button id="ai-speech-buildproject" type="primary" @click="submitFun">创建项目</el-button>
</div> </div>
</div> </div>
</div> </div>
@ -282,50 +333,72 @@
<script setup> <script setup>
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
const open = ref(false) const open = ref(false)
const selectTypeValue = ref(1);
const projectName = ref("");
const selectTemplateValue = ref({
name: '空白项目',
img: '',
url: '/dataScreen',
type: 1,
description: '空白模板',
size: 0
});
// //
const projectClassList = [ const projectClassList = [
{ {
name: '大屏看板', name: '大屏看板',
img: '/src/assets/images/sjdp1.png',
url: '/dataScreen'
},
{
name: '地图可视化',
img: '/src/assets/images/sjdp2.png', img: '/src/assets/images/sjdp2.png',
url: '/dataScreen' url: '/dataScreen',
type: 1
}, },
// {
// name: '',
// img: '/src/assets/images/sjdp2.png',
// url: '/dataScreen'
// },
{ {
name: '3D数字孪生', name: '3D数字孪生',
img: '/src/assets/images/sjdp1.png', img: '/src/assets/images/sjdp1.png',
url: '/dataScreen' url: '/dataScreen',
}, type: 2
{
name: '3D地理信息',
img: '/src/assets/images/sjdp2.png',
url: '/dataScreen'
},
{
name: 'BI看板',
img: '/src/assets/images/sjdp1.png',
url: '/dataScreen'
}, },
// {
// name: '3D',
// img: '/src/assets/images/sjdp2.png',
// url: '/dataScreen'
// },
// {
// name: 'BI',
// img: '/src/assets/images/sjdp1.png',
// url: '/dataScreen'
// },
] ]
// //
const largeScreenClassList = [ const largeScreenClassList = [
{ {
name: '空白项目', name: '空白项目',
img: '/src/assets/images/sjdp1.png', img: '',
url: '/dataScreen' url: '/dataScreen',
type: 1,
description: '空白模板',
size: 0
}, },
{ {
name: '新手入门示列', name: '新手入门示列',
img: '/src/assets/images/sjdp2.png', img: '/src/assets/images/sjdp2.png',
url: '/dataScreen' url: '/dataScreen',
type: 2,
description: '包含基础元素及新手演示视频',
size: 3
}, },
{ {
name: '大屏基础示列', name: '大屏基础示列',
img: '/src/assets/images/sjdp1.png', img: '/src/assets/images/sjdp1.png',
url: '/dataScreen' url: '/dataScreen',
type: 3,
description: '包含所有2D基础元素的大屏示列',
size: 5
}, },
] ]
@ -354,6 +427,15 @@ watch(open, (newVal) => {
emit('update:open', newVal) emit('update:open', newVal)
}) })
const selectType = (data) => {
selectTypeValue.value = data.type;
}
const selectTemplate = (data) => {
selectTemplateValue.value = data;
}
// //
const handleSubmit = () => { const handleSubmit = () => {
console.log('提交项目') console.log('提交项目')
@ -364,4 +446,8 @@ const handleSubmit = () => {
const handleClose = () => { const handleClose = () => {
open.value = false open.value = false
} }
const submitFun = () => {
console.log(projectName.value, "=====> 项目名称");
}
</script> </script>

View File

@ -66,7 +66,7 @@ const config = {
commands: [ commands: [
{ {
command: "add_project", command: "add_project",
description: "新建项目", description: "新建",
action: "click", action: "click",
selector: "#ai-speech-add-project", selector: "#ai-speech-add-project",
params: [], params: [],
@ -84,6 +84,27 @@ const config = {
}, },
], ],
}, },
{
command: "input_project_name",
description: "项目名称",
action: "input",
selector: "#ai-speech-project-name",
params: [
{
name: "projectname",
type: "string",
description: "输入项目名称",
},
],
},
{
command: "build_project",
description: "创建项目",
action: "click",
selector: "#ai-speech-buildproject",
params: [],
},
], ],
}; };
@ -218,7 +239,7 @@ class VoiceControl {
if (this.isListening) { if (this.isListening) {
// //
setTimeout(() => { setTimeout(() => {
this.recognition.start(); this.recognition.start();
}, 100); // }, 100); //
} else { } else {
this.updateUI(); this.updateUI();
@ -352,6 +373,10 @@ class VoiceControl {
} }
} }
delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async executeInstruction(instruction) { async executeInstruction(instruction) {
const commandConfig = this.config.commands.find( const commandConfig = this.config.commands.find(
(c) => c.command === instruction.command (c) => c.command === instruction.command
@ -363,7 +388,7 @@ class VoiceControl {
const element = document.querySelector(commandConfig.selector); const element = document.querySelector(commandConfig.selector);
console.log(element,"-----element"); console.log(element, "-----element");
if (!element) { if (!element) {
throw new Error(`找不到元素: ${commandConfig.selector}`); throw new Error(`找不到元素: ${commandConfig.selector}`);

View File

@ -6,7 +6,7 @@
<!-- 用户信息 --> <!-- 用户信息 -->
<div class="user-section"> <div class="user-section">
<div class="avatar"> <div class="avatar">
<img src="./../assets/default-photo.jpeg" alt="" /> <img src="/src/assets/default-photo.jpeg" alt="" />
</div> </div>
<div class="user-info"> <div class="user-info">
<div class="user-id">15586961409</div> <div class="user-id">15586961409</div>
@ -36,7 +36,7 @@
<!-- 广告卡片 --> <!-- 广告卡片 -->
<el-card header-class="card-header" body-class="card-body"> <el-card header-class="card-header" body-class="card-body">
<div class="card-content"> <div class="card-content">
<img src="./../assets/bg-1.png" style="width: 100%" /> <img src="/src/assets/bg-1.png" style="width: 100%" />
</div> </div>
</el-card> </el-card>
</aside> </aside>
@ -135,8 +135,6 @@ import projectModal from '@/view/components/projectModal.vue'
import { ref } from "vue"; import { ref } from "vue";
const dialogVisible = ref(false) const dialogVisible = ref(false)
const projectsrc = new URL("./../assets/images/sjdp1.png", import.meta.url).href;
const menu = ref([ const menu = ref([
{ {
name: "我的项目", name: "我的项目",
@ -176,7 +174,7 @@ const tabName = ref("local");
const projects = ref([ const projects = ref([
{ {
name: '苏州站基础大屏示例', name: '苏州站基础大屏示例',
img: projectsrc img: '/src/assets/images/sjdp1.png'
} }
]) ])