mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-28 01:53:53 +08:00
@@ -0,0 +1,54 @@
|
|||||||
|
import RequestService from '../httpRequest'
|
||||||
|
import {getServiceUrl} from '../api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* 设备激活接口
|
||||||
|
* @param {string} code 激活码
|
||||||
|
* @param {function} callback 回调函数
|
||||||
|
*/
|
||||||
|
activateDevice(code, callback) {
|
||||||
|
RequestService.sendRequest()
|
||||||
|
.url(`${getServiceUrl()}/api/v1/ota/activation`)
|
||||||
|
.method('GET')
|
||||||
|
.query({code})
|
||||||
|
.success((res) => {
|
||||||
|
RequestService.clearRequestTime()
|
||||||
|
callback(res)
|
||||||
|
})
|
||||||
|
.fail((err) => {
|
||||||
|
console.error('设备激活失败:', err)
|
||||||
|
RequestService.reAjaxFun(() => {
|
||||||
|
this.activateDevice(code, callback)
|
||||||
|
})
|
||||||
|
}).send()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查OTA版本和设备激活状态
|
||||||
|
* @param {object} deviceInfo 设备信息对象
|
||||||
|
* @param {string} deviceId 设备唯一标识
|
||||||
|
* @param {string} clientId 客户端标识
|
||||||
|
* @param {function} callback 回调函数
|
||||||
|
*/
|
||||||
|
checkOtaVersion(deviceInfo, deviceId, clientId, callback) {
|
||||||
|
RequestService.sendRequest()
|
||||||
|
.url(`${getServiceUrl()}/api/v1/ota`)
|
||||||
|
.method('POST')
|
||||||
|
.header({
|
||||||
|
'Device-Id': deviceId,
|
||||||
|
'Client-Id': clientId
|
||||||
|
})
|
||||||
|
.data(deviceInfo)
|
||||||
|
.success((res) => {
|
||||||
|
RequestService.clearRequestTime()
|
||||||
|
callback(res)
|
||||||
|
})
|
||||||
|
.fail((err) => {
|
||||||
|
console.error('检查OTA版本失败:', err)
|
||||||
|
RequestService.reAjaxFun(() => {
|
||||||
|
this.checkOtaVersion(deviceInfo, deviceId, clientId, callback)
|
||||||
|
})
|
||||||
|
}).send()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<span style="font-size: 11px"> 验证码:</span>
|
<span style="font-size: 11px"> 验证码:</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-46" style="margin-top: 12px;">
|
<div class="input-46" style="margin-top: 12px;">
|
||||||
<el-input placeholder="请输入设备播报的6位数验证码.." v-model="deviceCode" />
|
<el-input placeholder="请输入设备播报的6位数验证码.." v-model="deviceCode" @keyup.enter.native="confirm"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;margin: 15px 15px;gap: 7px;">
|
<div style="display: flex;margin: 15px 15px;gap: 7px;">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :visible.sync="visible" width="400px" center>
|
<el-dialog :visible.sync="visible" width="400px" center @open="handleOpen">
|
||||||
<div style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;">
|
<div style="margin: 0 10px 10px;display: flex;align-items: center;gap: 10px;font-weight: 700;font-size: 20px;text-align: left;color: #3d4566;">
|
||||||
<div style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;">
|
<div style="width: 40px;height: 40px;border-radius: 50%;background: #5778ff;display: flex;align-items: center;justify-content: center;">
|
||||||
<img loading="lazy" src="@/assets/home/equipment.png" alt="" style="width: 18px;height: 15px;" />
|
<img loading="lazy" src="@/assets/home/equipment.png" alt="" style="width: 18px;height: 15px;" />
|
||||||
@@ -12,7 +12,11 @@
|
|||||||
<div style="color: red;display: inline-block;">*</div> 智慧体名称:
|
<div style="color: red;display: inline-block;">*</div> 智慧体名称:
|
||||||
</div>
|
</div>
|
||||||
<div class="input-46" style="margin-top: 12px;">
|
<div class="input-46" style="margin-top: 12px;">
|
||||||
<el-input placeholder="请输入智能体名称.." v-model="wisdomBodyName" />
|
<el-input
|
||||||
|
ref="inputRef"
|
||||||
|
placeholder="请输入智能体名称.."
|
||||||
|
v-model="wisdomBodyName"
|
||||||
|
@keyup.enter.native="confirm" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;margin: 15px 15px;gap: 7px;">
|
<div style="display: flex;margin: 15px 15px;gap: 7px;">
|
||||||
@@ -31,16 +35,23 @@
|
|||||||
<script>
|
<script>
|
||||||
import userApi from '@/apis/module/agent';
|
import userApi from '@/apis/module/agent';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AddWisdomBodyDialog',
|
name: 'AddWisdomBodyDialog',
|
||||||
props: {
|
props: {
|
||||||
visible: { type: Boolean, required: true }
|
visible: { type: Boolean, required: true }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return { wisdomBodyName: "" }
|
return {
|
||||||
|
wisdomBodyName: "",
|
||||||
|
inputRef: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleOpen() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.inputRef.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
confirm() {
|
confirm() {
|
||||||
if (!this.wisdomBodyName.trim()) {
|
if (!this.wisdomBodyName.trim()) {
|
||||||
this.$message.error('请输入智能体名称');
|
this.$message.error('请输入智能体名称');
|
||||||
@@ -65,7 +76,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
.input-46 {
|
.input-46 {
|
||||||
border: 1px solid #e4e6ef;
|
border: 1px solid #e4e6ef;
|
||||||
background: #f6f8fb;
|
background: #f6f8fb;
|
||||||
|
|||||||
@@ -109,23 +109,26 @@ export default {
|
|||||||
// 处理搜索
|
// 处理搜索
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
const searchValue = this.search.trim();
|
const searchValue = this.search.trim();
|
||||||
let filteredDevices;
|
|
||||||
|
|
||||||
|
// 如果搜索内容为空,触发重置事件
|
||||||
if (!searchValue) {
|
if (!searchValue) {
|
||||||
// 当搜索内容为空时,显示原始完整列表
|
this.$emit('search-reset');
|
||||||
filteredDevices = this.$parent.originalDevices;
|
return;
|
||||||
} else {
|
|
||||||
// 过滤逻辑
|
|
||||||
filteredDevices = this.devices.filter(device => {
|
|
||||||
return device.agentName.includes(searchValue) ||
|
|
||||||
device.ttsModelName.includes(searchValue) ||
|
|
||||||
device.ttsVoiceName.includes(searchValue);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('search-result', filteredDevices);
|
try {
|
||||||
|
// 创建不区分大小写的正则表达式
|
||||||
|
const regex = new RegExp(searchValue, 'i');
|
||||||
|
// 触发搜索事件,将正则表达式传递给父组件
|
||||||
|
this.$emit('search', regex);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('正则表达式创建失败:', error);
|
||||||
|
this.$message.error({
|
||||||
|
message: '搜索关键词格式不正确',
|
||||||
|
showClose: true
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 显示修改密码弹窗
|
// 显示修改密码弹窗
|
||||||
showChangePasswordDialog() {
|
showChangePasswordDialog() {
|
||||||
this.isChangePasswordDialogVisible = true;
|
this.isChangePasswordDialogVisible = true;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="welcome">
|
<div class="welcome">
|
||||||
<!-- 公共头部 -->
|
<!-- 公共头部 -->
|
||||||
<HeaderBar :devices="devices" @search-result="handleSearchResult" />
|
<HeaderBar :devices="devices" @search="handleSearch" @search-reset="handleSearchReset" />
|
||||||
<el-main style="padding: 20px;display: flex;flex-direction: column;">
|
<el-main style="padding: 20px;display: flex;flex-direction: column;">
|
||||||
<div>
|
<div>
|
||||||
<!-- 首页内容 -->
|
<!-- 首页内容 -->
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;flex-wrap: wrap;margin-top: 20px;gap: 20px;justify-content: flex-start;box-sizing: border-box;">
|
<div class="device-list-container">
|
||||||
<DeviceItem v-for="(item,index) in devices" :key="index" :device="item"
|
<DeviceItem v-for="(item,index) in devices" :key="index" :device="item"
|
||||||
@configure="goToRoleConfig"
|
@configure="goToRoleConfig"
|
||||||
@deviceManage="handleDeviceManage"
|
@deviceManage="handleDeviceManage"
|
||||||
@@ -60,6 +60,8 @@ export default {
|
|||||||
addDeviceDialogVisible: false,
|
addDeviceDialogVisible: false,
|
||||||
devices: [],
|
devices: [],
|
||||||
originalDevices: [],
|
originalDevices: [],
|
||||||
|
isSearching: false,
|
||||||
|
searchRegex: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -83,22 +85,42 @@ export default {
|
|||||||
handleDeviceManage() {
|
handleDeviceManage() {
|
||||||
this.$router.push('/device-management');
|
this.$router.push('/device-management');
|
||||||
},
|
},
|
||||||
// 获取智能体列表
|
handleSearch(regex) {
|
||||||
fetchAgentList() {
|
this.isSearching = true;
|
||||||
import('@/apis/module/agent').then(({ default: userApi }) => {
|
this.searchRegex = regex;
|
||||||
userApi.getAgentList(({data}) => {
|
this.applySearchFilter();
|
||||||
this.originalDevices = data.data.map(item => ({
|
},
|
||||||
...item,
|
handleSearchReset() {
|
||||||
agentId: item.id // 字段映射
|
this.isSearching = false;
|
||||||
}));
|
this.searchRegex = null;
|
||||||
this.devices = this.originalDevices;
|
this.devices = [...this.originalDevices];
|
||||||
});
|
},
|
||||||
|
applySearchFilter() {
|
||||||
|
if (!this.isSearching || !this.searchRegex) {
|
||||||
|
this.devices = [...this.originalDevices];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.devices = this.originalDevices.filter(device => {
|
||||||
|
return this.searchRegex.test(device.agentName);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 搜索更新智能体列表
|
// 搜索更新智能体列表
|
||||||
handleSearchResult(filteredList) {
|
handleSearchResult(filteredList) {
|
||||||
this.devices = filteredList; // 更新设备列表
|
this.devices = filteredList; // 更新设备列表
|
||||||
},
|
},
|
||||||
|
// 获取智能体列表
|
||||||
|
fetchAgentList() {
|
||||||
|
import('@/apis/module/agent').then(({ default: userApi }) => {
|
||||||
|
userApi.getAgentList(({data}) => {
|
||||||
|
this.originalDevices = data.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
agentId: item.id // 字段映射
|
||||||
|
}));
|
||||||
|
this.handleSearchReset(); // 重置搜索状态
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
// 删除智能体
|
// 删除智能体
|
||||||
handleDeleteAgent(agentId) {
|
handleDeleteAgent(agentId) {
|
||||||
this.$confirm('确定要删除该智能体吗?', '提示', {
|
this.$confirm('确定要删除该智能体吗?', '提示', {
|
||||||
@@ -220,4 +242,27 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.device-list-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
padding: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 在 DeviceItem.vue 的样式中 */
|
||||||
|
.device-item {
|
||||||
|
margin: 0 !important; /* 避免冲突 */
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-top: auto;
|
||||||
|
padding-top: 30px;
|
||||||
|
color: #979db1;
|
||||||
|
text-align: center; /* 居中显示 */
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user