mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 00:23:53 +08:00
feature:
1.OTA基本能力(固定配置),待优化 2.智能体管理与设备管理对接api,实现流程闭环(已测试)
This commit is contained in:
@@ -9,9 +9,9 @@ import user from './module/user.js'
|
||||
* 如果你想调用8002端口,就用'/xiaozhi-esp32-api/api/v1',请与vue.config.js的devServer配置相结合,方便跨域请求
|
||||
*
|
||||
*/
|
||||
const DEV_API_SERVICE = 'https://m1.apifoxmock.com/m1/5931378-5618560-default'
|
||||
// const DEV_API_SERVICE = 'https://m1.apifoxmock.com/m1/5931378-5618560-default'
|
||||
// 8002开发完成完成后使用这个
|
||||
// const DEV_API_SERVICE = '/xiaozhi-esp32-api'
|
||||
const DEV_API_SERVICE = '/xiaozhi-esp32-api'
|
||||
|
||||
/**
|
||||
* 根据开发环境返回接口url
|
||||
|
||||
@@ -16,20 +16,17 @@ export default {
|
||||
}).send()
|
||||
},
|
||||
//添加智能体
|
||||
addAgent(name, callback) {
|
||||
addAgent(agentName, callback) {
|
||||
RequestService.sendRequest()
|
||||
.url(`${getServiceUrl()}/api/v1/user/agent`)
|
||||
.method('POST')
|
||||
.data({name})
|
||||
.data({agentName})
|
||||
.success((res) => {
|
||||
RequestService.clearRequestTime();
|
||||
callback(res);
|
||||
})
|
||||
.fail((err) => {
|
||||
console.error('添加智能体失败:', err);
|
||||
RequestService.reAjaxFun(() => {
|
||||
this.addAgent(name, callback);
|
||||
});
|
||||
}).send();
|
||||
},
|
||||
//获取智能体配置
|
||||
|
||||
@@ -4,9 +4,10 @@ import {getServiceUrl} from '../api'
|
||||
|
||||
export default {
|
||||
//设备列表
|
||||
getDeviceList(agent_id, callback) {
|
||||
getDeviceList(agent_id, page, callback) {
|
||||
RequestService.sendRequest().url(`${getServiceUrl()}/api/v1/user/agent/device/bind/${agent_id}`)
|
||||
.method('GET')
|
||||
.data(page)
|
||||
.success((res) => {
|
||||
RequestService.clearRequestTime()
|
||||
callback(res)
|
||||
@@ -16,11 +17,11 @@ export default {
|
||||
}).send()
|
||||
},
|
||||
//绑定设备
|
||||
bindDevice(agent_id, code, callback) {
|
||||
bindDevice(agentId, deviceCode, callback) {
|
||||
RequestService.sendRequest()
|
||||
.url(`${getServiceUrl()}/api/v1/user/agent/device/bind/${agent_id}`)
|
||||
.url(`${getServiceUrl()}/api/v1/user/agent/device/bind/${agentId}`)
|
||||
.method('POST')
|
||||
.data({code})
|
||||
.data({deviceCode})
|
||||
.success((res) => {
|
||||
RequestService.clearRequestTime();
|
||||
callback(res);
|
||||
@@ -28,14 +29,14 @@ export default {
|
||||
.fail((err) => {
|
||||
console.error('绑定设备失败:', err);
|
||||
RequestService.reAjaxFun(() => {
|
||||
this.addDevice(name, callback);
|
||||
this.addDevice(agentId, deviceCode, callback);
|
||||
});
|
||||
}).send();
|
||||
},
|
||||
// 解绑设备
|
||||
unbindDevice(device_id, callback) {
|
||||
unbindDevice(deviceId, callback) {
|
||||
RequestService.sendRequest()
|
||||
.url(`${getServiceUrl()}/api/v1/user/device/unbind/${device_id}`)
|
||||
.url(`${getServiceUrl()}/api/v1/user/agent/device/unbind/${deviceId}`)
|
||||
.method('PUT')
|
||||
.success((res) => {
|
||||
RequestService.clearRequestTime();
|
||||
@@ -43,7 +44,7 @@ export default {
|
||||
})
|
||||
.fail(() => {
|
||||
RequestService.reAjaxFun(() => {
|
||||
this.unbindDevice(device_id, callback);
|
||||
this.unbindDevice(deviceId, callback);
|
||||
});
|
||||
}).send()
|
||||
},
|
||||
|
||||
@@ -46,12 +46,13 @@ export default {
|
||||
this.$message.error('请输入智能体名称');
|
||||
return;
|
||||
}
|
||||
userApi.addAgent(this.agentName, (res) => {
|
||||
this.$message.success('添加成功');
|
||||
this.$emit('confirm', res);
|
||||
this.$emit('confirm',this.agentName)
|
||||
// userApi.addAgent(this.agentName, (res) => {
|
||||
// this.$message.success('添加成功');
|
||||
// this.$emit('confirm', res);
|
||||
this.$emit('update:visible', false);
|
||||
this.agentName = "";
|
||||
});
|
||||
// });
|
||||
},
|
||||
cancel() {
|
||||
this.$emit('update:visible', false)
|
||||
|
||||
@@ -40,8 +40,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
if (!this.deviceCode.trim()) {
|
||||
this.$message.error('请输入设备验证码');
|
||||
return;
|
||||
}
|
||||
this.$emit('confirm',this.deviceCode)
|
||||
this.$emit('update:visible', false)
|
||||
this.$emit('added', this.deviceCode)
|
||||
this.deviceCode = ""
|
||||
},
|
||||
cancel() {
|
||||
|
||||
@@ -39,10 +39,13 @@ function formatDateTool(date, fmt) {
|
||||
const o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'H+': date.getHours(),
|
||||
'h+': date.getHours() > 12 ? date.getHours() - 12 : date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
}
|
||||
// 12小时制
|
||||
const is_12Hours = fmt.indexOf('hh') > -1;
|
||||
for (const k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
const str = o[k] + ''
|
||||
@@ -52,6 +55,8 @@ function formatDateTool(date, fmt) {
|
||||
)
|
||||
}
|
||||
}
|
||||
// 12小时制
|
||||
fmt = is_12Hours ? date.getHours() > 12 ? fmt + " PM" : fmt + " AM" : fmt
|
||||
return fmt
|
||||
}
|
||||
|
||||
|
||||
@@ -18,50 +18,53 @@
|
||||
+ 添加设备
|
||||
</el-button>
|
||||
<el-table :data="devices" style="width: 100%; margin-top: 20px" border>
|
||||
<el-table-column label="设备型号" prop="device_type" flex></el-table-column>
|
||||
<el-table-column label="固件版本" prop="app_version" width="140"></el-table-column>
|
||||
<el-table-column label="MAC地址" prop="mac_address" width="220"></el-table-column>
|
||||
<el-table-column label="绑定时间" prop="bind_time" width="260"></el-table-column>
|
||||
<el-table-column label="设备型号" prop="board" flex></el-table-column>
|
||||
<el-table-column label="固件版本" prop="appVersion" width="140"></el-table-column>
|
||||
<el-table-column label="MAC地址" prop="macAddress" width="220"></el-table-column>
|
||||
<el-table-column label="绑定时间" width="260" prop="createDate" :formatter="formatter">
|
||||
</el-table-column>
|
||||
<el-table-column label="最近对话" prop="recent_chat_time" width="100"></el-table-column>
|
||||
<el-table-column label="备注" width="220">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-if="scope.row.isEdit" v-model="scope.row.remark" size="small" @blur="stopEditRemark(scope.$index)"></el-input>
|
||||
<el-input v-if="scope.row.isEdit" v-model="scope.row.alias" size="small" @blur="stopEditRemark(scope.$index)"></el-input>
|
||||
<span v-else>
|
||||
{{ scope.row.remark }}
|
||||
{{ scope.row.alias }}
|
||||
</span>
|
||||
<i v-if="!scope.row.isEdit" class="el-icon-edit" @click="startEditRemark(scope.$index, scope.row)"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="OTA升级" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="scope.row.ota_upgrade" size="mini" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
|
||||
<el-switch v-model="scope.row.autoUpdate" size="mini" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" @click="handleUnbind(scope.row)" style="color: #ff4949">
|
||||
<el-button size="mini" type="text" @click="handleUnbind(scope.row.id)" style="color: #ff4949">
|
||||
解绑
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<el-pagination background :page-size="10" :pager-count="5" layout="prev, pager, next" :total="150" style="margin-top: 4px;text-align: right;"></el-pagination>
|
||||
<el-pagination background :current-page="page.pageNo" :page-size="page.pageSize" :pager-count="5" layout="prev, pager, next" :total="page.total" style="margin-top: 4px;text-align: right;"></el-pagination>
|
||||
</div>
|
||||
<!-- 底部 -->
|
||||
<Footer :visible="true" />
|
||||
<!-- 添加设备对话框 -->
|
||||
<AddDeviceDialog :visible.sync="addDeviceDialogVisible" @added="handleDeviceAdded" />
|
||||
<AddDeviceDialog :visible.sync="addDeviceDialogVisible" @confirm="handleDeviceBind" />
|
||||
</el-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUUID, goToPage, showDanger, showSuccess} from '@/utils'
|
||||
import { formatDate } from '@/utils/date'
|
||||
import Api from '@/apis/api';
|
||||
import AddDeviceDialog from '@/components/AddDeviceDialog.vue'
|
||||
import HeaderBar from '@/components/HeaderBar.vue'
|
||||
import Footer from '@/components/Footer.vue'
|
||||
import api from '@/apis/api';
|
||||
|
||||
export default {
|
||||
name: 'DevicePage',
|
||||
@@ -70,18 +73,24 @@ export default {
|
||||
return {
|
||||
addDeviceDialogVisible: false,
|
||||
devices: [],
|
||||
agentId: this.$route.query.agentId
|
||||
agentId: this.$route.query.agentId,
|
||||
page: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getDeviceList();
|
||||
this.fetchDeviceList();
|
||||
},
|
||||
methods: {
|
||||
// 获取设备列表
|
||||
getDeviceList() {
|
||||
Api.device.getDeviceList(this.agentId, ({data}) => {
|
||||
fetchDeviceList() {
|
||||
Api.device.getDeviceList(this.agentId, this.page, ({data}) => {
|
||||
if (data.code === 0) {
|
||||
this.devices = data.data[0].list.map((item)=>{item.isEdit=false;return item;})
|
||||
this.page = {...this.page,total:parseInt(data.data.total)}
|
||||
this.devices = data.data.records.map((item)=>{item.isEdit=false;return item;})
|
||||
} else {
|
||||
showDanger(data.msg)
|
||||
}
|
||||
@@ -97,14 +106,33 @@ export default {
|
||||
stopEditRemark(index) {
|
||||
this.devices[index].isEdit = false;
|
||||
},
|
||||
handleUnbind(device) {
|
||||
handleUnbind(deviceId) {
|
||||
// 解绑逻辑
|
||||
console.log('解绑设备', device);
|
||||
console.log('解绑设备', deviceId);
|
||||
Api.device.unbindDevice(deviceId, ({data}) => {
|
||||
if (data.code === 0) {
|
||||
showSuccess('解绑成功')
|
||||
this.fetchDeviceList()
|
||||
} else {
|
||||
showDanger(data.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDeviceAdded(deviceCode) {
|
||||
handleDeviceBind(deviceCode) {
|
||||
// 根据需要处理添加设备后逻辑,比如刷新设备列表等
|
||||
console.log('设备验证码:', deviceCode)
|
||||
Api.device.bindDevice(this.agentId, deviceCode, ({data}) => {
|
||||
if (data.code === 0) {
|
||||
this.fetchDeviceList();
|
||||
this.showBindDialog = false;
|
||||
} else {
|
||||
showDanger(data.msg);
|
||||
}
|
||||
})
|
||||
},
|
||||
formatter(row, column) {
|
||||
return formatDate(row.createDate)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="welcome">
|
||||
<!-- 公共头部 -->
|
||||
<HeaderBar :devices="devices" @search-result="handleSearchResult" />
|
||||
<HeaderBar :devices="agents" @search-result="handleSearchResult" />
|
||||
<el-main style="padding: 20px;display: flex;flex-direction: column;">
|
||||
<div>
|
||||
<!-- 首页内容 -->
|
||||
@@ -45,7 +45,7 @@
|
||||
<!-- 底部 -->
|
||||
<Footer :visible="true" />
|
||||
<!-- 添加设备对话框 -->
|
||||
<AddAgentDialog :visible.sync="addAgentDialogVisible" @added="handleAgentAdded" />
|
||||
<AddAgentDialog :visible.sync="addAgentDialogVisible" @confirm="handleAgentAdded" />
|
||||
</el-main>
|
||||
</div>
|
||||
|
||||
@@ -120,7 +120,7 @@ export default {
|
||||
},
|
||||
// 搜索更新智能体列表
|
||||
handleSearchResult(filteredList) {
|
||||
this.devices = filteredList; // 更新设备列表
|
||||
this.agents = filteredList; // 更新设备列表
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,19 +119,19 @@ export default {
|
||||
intent:""
|
||||
}
|
||||
},
|
||||
options: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶' }
|
||||
],
|
||||
options: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶' }
|
||||
],
|
||||
models: [
|
||||
{ label: '大语言模型(LLM)', key: 'llm' },
|
||||
{ label: '语音转文本模型(ASR)', key: 'asr' },
|
||||
{ label: '语音活动检测模型(VAD)', key: 'vad' },
|
||||
{ label: '语音生成模型(TTS)', key: 'tts' },
|
||||
{ label: '意图分类模型(Intent)', key: 'intent' },
|
||||
{ label: '记忆增强模型(Memory)', key: 'memory' }
|
||||
],
|
||||
templates: ['台湾女友', '土豆子', '英语老师', '好奇小男孩', '汪汪队队长']
|
||||
{ label: '大语言模型(LLM)', key: 'llm' },
|
||||
{ label: '语音转文本模型(ASR)', key: 'asr' },
|
||||
{ label: '语音活动检测模型(VAD)', key: 'vad' },
|
||||
{ label: '语音生成模型(TTS)', key: 'tts' },
|
||||
{ label: '意图分类模型(Intent)', key: 'intent' },
|
||||
{ label: '记忆增强模型(Memory)', key: 'memory' }
|
||||
],
|
||||
templates: ['通用男声','通用女声','阳光男生','奶气萌娃']
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user