mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-23 23:53:55 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0f777b9b4 | ||
|
|
dfe3de14d8 | ||
|
|
abe234c7ce | ||
|
|
d7bf67fd0e | ||
|
|
8218996f04 | ||
|
|
a5444b11b3 | ||
|
|
5648ee974a | ||
|
|
6cd88fb98f | ||
|
|
3ea1a2bf2f |
@@ -0,0 +1,149 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :visible.sync="dialogVisible" width="900px" @close="handleClose" class="compact-dialog" :append-to-body="true">
|
||||||
|
<el-form :model="voiceForm" :rules="rules" ref="voiceForm" label-width="80px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="音色编码" prop="voiceCode">
|
||||||
|
<el-input v-model="voiceForm.voiceCode" placeholder="请输入内容" class="compact-input"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="音色名称" prop="voiceName">
|
||||||
|
<el-input v-model="voiceForm.voiceName" placeholder="请输入内容" class="compact-input"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="语言类型" prop="languageType">
|
||||||
|
<el-input v-model="voiceForm.languageType" placeholder="请输入内容" class="compact-input"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="排序号" prop="sortNumber">
|
||||||
|
<el-input-number v-model="voiceForm.sortNumber" :min="1" :controls="false" class="compact-number"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="voiceForm.remark" type="textarea" :rows="2" placeholder="请输入内容" class="compact-textarea"
|
||||||
|
></el-input>
|
||||||
|
<div class="audio-controls">
|
||||||
|
<div class="audio-player">
|
||||||
|
<audio
|
||||||
|
:src="audioUrl"
|
||||||
|
controls
|
||||||
|
preload="metadata"
|
||||||
|
class="custom-audio"
|
||||||
|
></audio>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" size="mini" class="preview-btn">生成试听</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||||
|
<el-button type="primary" @click="handleClose">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'EditVoiceDialog',
|
||||||
|
props: {
|
||||||
|
showDialog: Boolean,
|
||||||
|
voiceData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
voiceCode: 'wawaxiaohe',
|
||||||
|
voiceName: '湾湾小何',
|
||||||
|
languageType: '中文',
|
||||||
|
sortNumber: 123
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: this.showDialog,
|
||||||
|
voiceForm: { ...this.voiceData },
|
||||||
|
audioUrl: 'http://music.163.com/song/media/outer/url?id=447925558.mp3',
|
||||||
|
generatedAudio: null,
|
||||||
|
rules: {
|
||||||
|
voiceCode: [{ required: true, message: '请输入音色编码', trigger: 'blur' }],
|
||||||
|
voiceName: [{ required: true, message: '请输入音色名称', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
showDialog(newVal) {
|
||||||
|
this.dialogVisible = newVal
|
||||||
|
if (newVal) this.voiceForm = { ...this.voiceData }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.$emit('update:showDialog', false)
|
||||||
|
},
|
||||||
|
handleSave() {
|
||||||
|
this.$refs.voiceForm.validate(valid => {
|
||||||
|
if (valid) this.$emit('save', this.voiceForm)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.compact-dialog {
|
||||||
|
/deep/ .el-dialog__body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compact-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compact-number {
|
||||||
|
width: 100%;
|
||||||
|
/deep/ .el-input__inner {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.compact-textarea {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 8px;
|
||||||
|
|
||||||
|
|
||||||
|
.preview-btn {
|
||||||
|
padding: 7px 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
padding: 16px 20px 0;
|
||||||
|
text-align: right;
|
||||||
|
border-top: 1px solid #EBEEF5;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -8,13 +8,11 @@
|
|||||||
<img alt="" src="@/assets/home/equipment.png" style="width: 12px;height: 10px;"/>
|
<img alt="" src="@/assets/home/equipment.png" style="width: 12px;height: 10px;"/>
|
||||||
智能体管理
|
智能体管理
|
||||||
</div>
|
</div>
|
||||||
<div class="console">
|
<div class="equipment-management2" :class="{ 'active-tab': $route.path === '/user-management' }" @click="goUserManagement">
|
||||||
<i class="el-icon-s-grid" style="font-size: 10px;color: #979db1;"/>
|
用户管理
|
||||||
控制台
|
|
||||||
</div>
|
</div>
|
||||||
<div class="equipment-management2">
|
<div class="equipment-management2" :class="{ 'active-tab': $route.path === '/model-config' }" @click="goModelConfig">
|
||||||
设备管理
|
模型配置
|
||||||
<img alt="" src="@/assets/home/close.png" style="width: 6px;height: 6px;"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;align-items: center;gap: 7px; margin-top: 2px;">
|
<div style="display: flex;align-items: center;gap: 7px; margin-top: 2px;">
|
||||||
@@ -64,6 +62,12 @@ export default {
|
|||||||
// 跳转到首页
|
// 跳转到首页
|
||||||
this.$router.push('/')
|
this.$router.push('/')
|
||||||
},
|
},
|
||||||
|
goUserManagement() {
|
||||||
|
this.$router.push('/user-management')
|
||||||
|
},
|
||||||
|
goModelConfig() {
|
||||||
|
this.$router.push('/model-config')
|
||||||
|
},
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
fetchUserInfo() {
|
fetchUserInfo() {
|
||||||
userApi.getUserInfo(({data}) => {
|
userApi.getUserInfo(({data}) => {
|
||||||
@@ -117,18 +121,24 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.equipment-management2 {
|
.equipment-management2 {
|
||||||
width: 87px;
|
width: 82px;
|
||||||
height: 22px;
|
height: 24px;
|
||||||
border-radius: 11px;
|
border-radius: 12px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 9px;
|
font-size: 10px;
|
||||||
font-weight: 400;
|
font-weight: 500;
|
||||||
gap: 7px;
|
gap: 7px;
|
||||||
color: #3d4566;
|
color: #3d4566;
|
||||||
margin-left: 2px;
|
margin-left: 1px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equipment-management2.active-tab {
|
||||||
|
background: #5778ff !important;
|
||||||
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@@ -168,28 +178,4 @@ export default {
|
|||||||
color: #3d4566;
|
color: #3d4566;
|
||||||
}
|
}
|
||||||
|
|
||||||
.console {
|
|
||||||
width: 90px;
|
|
||||||
height: 22px;
|
|
||||||
border-radius: 11px;
|
|
||||||
background: radial-gradient(50% 50% at 50% 50%, #fff 0%, #e8f0ff 100%);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 9px;
|
|
||||||
color: #979db1;
|
|
||||||
font-weight: 400;
|
|
||||||
gap: 7px;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-dropdown-link {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #5778ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-icon-arrow-down {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :visible.sync="dialogVisible" width="800px" center>
|
||||||
|
<el-form :model="form" ref="form" label-width="70px">
|
||||||
|
<el-row :gutter="20" class="form-row">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="模型编码">
|
||||||
|
<el-input v-model="form.code" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="模型名称">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 供应商 -->
|
||||||
|
<el-row :gutter="20" class="form-row">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="供应器">
|
||||||
|
<el-select v-model="form.supplier" placeholder="请选择">
|
||||||
|
<el-option label="openai" value="openai" />
|
||||||
|
<el-option label="dify" value="dify" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<span class="el-form-item__label" style="width: 70px;">设成默认</span>
|
||||||
|
<el-switch v-model="form.isDefault" style="margin-right: 20px;" />
|
||||||
|
<span class="el-form-item__label" style="width: 70px;">是否启用</span>
|
||||||
|
<el-switch v-model="form.isEnable" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 文档 -->
|
||||||
|
<el-row :gutter="20" class="form-row">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="文档地址">
|
||||||
|
<el-input v-model="form.docUrl" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="排序号">
|
||||||
|
<el-input-number v-model="form.sort" :min="1" :max="999" controls-position="right" placeholder="123"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 备注 -->
|
||||||
|
<el-form-item label="备注" class="form-row">
|
||||||
|
<el-input type="textarea" v-model="form.remark" :rows="2" placeholder="请输入"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div class="vertical-fields">
|
||||||
|
<el-form-item label="接口地址">
|
||||||
|
<el-input v-model="form.apiUrl" placeholder="请输入base_url" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模型名称">
|
||||||
|
<el-input v-model="form.modelName" placeholder="请输入model_name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密钥信息">
|
||||||
|
<el-input v-model="form.apiKey" placeholder="请输入api_key" show-password/>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ModelConfigDialog",
|
||||||
|
props: {
|
||||||
|
visible: { type: Boolean, default: false },
|
||||||
|
configData: { type: Object, default: () => ({}) }
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: this.visible,
|
||||||
|
form: {
|
||||||
|
code: "",
|
||||||
|
name: "",
|
||||||
|
supplier: "",
|
||||||
|
isDefault: true,
|
||||||
|
isEnable: true,
|
||||||
|
docUrl: "",
|
||||||
|
sort: 123,
|
||||||
|
remark: "",
|
||||||
|
apiUrl: "",
|
||||||
|
modelName: "",
|
||||||
|
apiKey: ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dialogVisible(val) {
|
||||||
|
this.$emit('update:visible', val);
|
||||||
|
},
|
||||||
|
visible(val) {
|
||||||
|
this.dialogVisible = val;
|
||||||
|
if (val) this.form = { ...this.form, ...this.configData };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSave() {
|
||||||
|
this.$emit("submit", this.form);
|
||||||
|
this.dialogVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dialog-footer {
|
||||||
|
margin-top: -30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.el-input-number {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.form-row {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-fields {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
margin-top: -10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.el-input-number {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item__label {
|
||||||
|
text-align: left;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :visible.sync="visible" width="80%" @close="handleClose">
|
||||||
|
<el-row class="main-container">
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-menu class="model-menu" :default-active="activeModel" mode="vertical" @select="handleModelSelect">
|
||||||
|
<el-menu-item index="EdgeTTS">EdgeTTS</el-menu-item>
|
||||||
|
<el-menu-item index="DoubaoTTS">DoubaoTTS</el-menu-item>
|
||||||
|
<el-menu-item index="TTS302AI">TTS302AI</el-menu-item>
|
||||||
|
<el-menu-item index="CosyVoiceSiliconflow">CosyVoiceSiliconflow</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="20">
|
||||||
|
<div class="search-operate">
|
||||||
|
<el-input placeholder="请输入音色名称查询" v-model="searchQuery" style="width: 300px; margin-right: 10px;"/>
|
||||||
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleAddVoice">添加音色</el-button>
|
||||||
|
<el-button type="danger" plain @click="handleBatchDelete">批量删除</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="filteredTtsModels" style="width: 100%" border stripe header-row-class-name="table-header">
|
||||||
|
<el-table-column label="音色编码" prop="voiceCode" width="150" align="center"></el-table-column>
|
||||||
|
<el-table-column label="音色名称" prop="voiceName" width="180" align="center"></el-table-column>
|
||||||
|
<el-table-column label="语言类型" prop="languageType" width="120" align="center"></el-table-column>
|
||||||
|
<el-table-column label="备注" prop="remark" align="center"></el-table-column>
|
||||||
|
<el-table-column label="操作" width="200" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button size="mini" type="text" @click="editVoice(scope.row)" style="color: #409EFF; margin-right: 15px;">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" @click="deleteVoice(scope.row)" style="color: #F56C6C;">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination :current-page="currentPage" :page-size="pageSize" :total="total" layout="prev, pager, next" prev-text="<" next-text=">"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose" size="medium">关闭</el-button>
|
||||||
|
<el-button type="primary" @click="handleImportExport" size="medium">导入导出配置</el-button>
|
||||||
|
</div>
|
||||||
|
<EditVoiceDialog :showDialog="editDialogVisible" :voiceData="editVoiceData" @update:showDialog="editDialogVisible = $event" @saveVoice="handleSaveEditedVoice"/>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import EditVoiceDialog from "@/components/EditVoiceDialog.vue";
|
||||||
|
export default {
|
||||||
|
components: { EditVoiceDialog },
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeModel: 'EdgeTTS',
|
||||||
|
searchQuery: '',
|
||||||
|
editDialogVisible: false,
|
||||||
|
editVoiceData: {},
|
||||||
|
ttsModels: [
|
||||||
|
{ voiceCode: 'wawaxiaohe', voiceName: '湾湾小何', languageType: '中文', remark: '' },
|
||||||
|
{ voiceCode: 'wawaxiaohe', voiceName: '湾湾小何', languageType: '中文', remark: '' },
|
||||||
|
{ voiceCode: 'wawaxiaohe', voiceName: '湾湾小何', languageType: '中文', remark: '' },
|
||||||
|
{ voiceCode: 'wawaxiaohe', voiceName: '湾湾小何', languageType: '中文', remark: '' },
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 4,
|
||||||
|
total: 20
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredTtsModels() {
|
||||||
|
return this.ttsModels.filter(model =>
|
||||||
|
model.voiceName.toLowerCase().includes(this.searchQuery.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {
|
||||||
|
this.$emit('update:visible', false);
|
||||||
|
},
|
||||||
|
handleModelSelect(index) {
|
||||||
|
this.activeModel = index;
|
||||||
|
// 可根据选中模型加载对应数据
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
// 搜索
|
||||||
|
},
|
||||||
|
handleAddVoice() {
|
||||||
|
// 添加音色
|
||||||
|
},
|
||||||
|
handleBatchDelete() {
|
||||||
|
// 批量删除
|
||||||
|
},
|
||||||
|
editVoice(voice) {
|
||||||
|
this.editVoiceData = { ...voice };
|
||||||
|
this.editDialogVisible = true;
|
||||||
|
},
|
||||||
|
handleSaveEditedVoice(voiceForm) {
|
||||||
|
const index = this.ttsModels.findIndex(item => item.voiceCode === voiceForm.voiceCode);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.ttsModels.splice(index, 1, voiceForm);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteVoice(voice) {
|
||||||
|
// 删除
|
||||||
|
},
|
||||||
|
handleImportExport() {
|
||||||
|
// 导入导出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.main-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-menu {
|
||||||
|
border-right: 1px solid #ebeef5;
|
||||||
|
height: calc(100vh - 300px);
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-operate {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
margin: 20px 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: right;
|
||||||
|
padding: 20px 20px 0;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .table-header th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-table--border td, ::v-deep .el-table--border th {
|
||||||
|
border-right: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination .btn-prev, ::v-deep .el-pagination .btn-next {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination .btn-prev:hover, ::v-deep .el-pagination .btn-next:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination .el-pager li {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination .el-pager li:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-pagination .el-pager li.active {
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #409EFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -39,15 +39,30 @@ const routes = [
|
|||||||
return import('../views/register.vue')
|
return import('../views/register.vue')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 新增设备管理页面路由
|
// 设备管理页面路由
|
||||||
{
|
{
|
||||||
path: '/device-management',
|
path: '/device-management',
|
||||||
name: 'DeviceManagement',
|
name: 'DeviceManagement',
|
||||||
component: function () {
|
component: function () {
|
||||||
return import('../views/DeviceManagement.vue')
|
return import('../views/DeviceManagement.vue')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// 添加用户管理路由
|
||||||
|
{
|
||||||
|
path: '/user-management',
|
||||||
|
name: 'UserManagement',
|
||||||
|
component: function () {
|
||||||
|
return import('../views/UserManagement.vue')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/model-config',
|
||||||
|
name: 'ModelConfig',
|
||||||
|
component: function () {
|
||||||
|
return import('../views/ModelConfig.vue')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<el-table :data="deviceList" style="width: 100%; margin-top: 20px" border stripe>
|
<el-table :data="deviceList" style="width: 100%; margin-top: 20px" border stripe>
|
||||||
<el-table-column label="设备型号" prop="model" flex></el-table-column>
|
<el-table-column label="设备型号" prop="model" flex></el-table-column>
|
||||||
<el-table-column label="固件版本" prop="firmwareVersion" width="140"></el-table-column>
|
<el-table-column label="固件版本" prop="firmwareVersion" width="120"></el-table-column>
|
||||||
<el-table-column label="Mac地址" prop="macAddress" width="220"></el-table-column>
|
<el-table-column label="Mac地址" prop="macAddress"></el-table-column>
|
||||||
<el-table-column label="绑定时间" prop="bindTime" width="260"></el-table-column>
|
<el-table-column label="绑定时间" prop="bindTime" width="200"></el-table-column>
|
||||||
<el-table-column label="最近对话" prop="lastConversation" width="100"></el-table-column>
|
<el-table-column label="最近对话" prop="lastConversation" width="140"></el-table-column>
|
||||||
<el-table-column label="备注" width="220">
|
<el-table-column label="备注" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-input v-if="scope.row.isEdit" v-model="scope.row.remark" size="mini" @blur="stopEditRemark(scope.$index)"></el-input>
|
<el-input v-if="scope.row.isEdit" v-model="scope.row.remark" size="mini" @blur="stopEditRemark(scope.$index)"></el-input>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
@@ -85,7 +85,7 @@ export default {
|
|||||||
remark: '生产环境设备',
|
remark: '生产环境设备',
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
otaSwitch: false
|
otaSwitch: false
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,199 @@
|
|||||||
|
<template>
|
||||||
|
<div class="welcome">
|
||||||
|
<HeaderBar />
|
||||||
|
<div class="model-tabs-container">
|
||||||
|
<el-tabs v-model="activeTab" class="model-tabs" >
|
||||||
|
<el-tab-pane label="语音活动检测模型(VAD)" name="vad"></el-tab-pane>
|
||||||
|
<el-tab-pane label="语音识别(ASR)" name="asr"></el-tab-pane>
|
||||||
|
<el-tab-pane label="大语言模型(LLM)" name="llm"></el-tab-pane>
|
||||||
|
<el-tab-pane label="意图识别模型(Intent)" name="intent"></el-tab-pane>
|
||||||
|
<el-tab-pane label="语音合成模型(TTS)" name="tts"></el-tab-pane>
|
||||||
|
<el-tab-pane label="记忆模型(Memory)" name="memory"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="import-export-btn">
|
||||||
|
<el-button v-if="activeTab === 'tts'" type="primary" @click="ttsDialogVisible = true" style="margin-right: 10px;">模型设置</el-button>
|
||||||
|
<el-button size="small" @click="handleImportExport">导入导出配置</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-main style="padding: 20px; display: flex; flex-direction: column;">
|
||||||
|
|
||||||
|
<el-card class="model-card" shadow="always">
|
||||||
|
<div class="model-search-operate" style="display: flex; align-items: center; margin-bottom: 20px;">
|
||||||
|
<el-input placeholder="请输入模型名称查询" v-model="search" style="width: 300px; margin-right: 10px" />
|
||||||
|
<el-button @click="handleSearch">查询</el-button>
|
||||||
|
<el-button type="primary" @click="addModel">增加模型</el-button>
|
||||||
|
<el-button type="danger" @click="batchDelete">批量删除</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="modelList" style="width: 100%;" border stripe>
|
||||||
|
<el-table-column label="模型编码" prop="code"></el-table-column>
|
||||||
|
<el-table-column label="模型名称" prop="candidateName"></el-table-column>
|
||||||
|
<el-table-column label="是否应用">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="scope.row.isApplied ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.isApplied ? '是' : '否' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="供应商名称" prop="supplier"></el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button size="mini" @click="editModel(scope.row)" style="margin-right: 10px;">修改</el-button>
|
||||||
|
<el-button size="mini" type="danger" @click="deleteModel(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-sizes="[5, 10, 15]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="prev, pager, next"
|
||||||
|
:total="total"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="font-size: 12px; font-weight: 400; margin-top: auto; padding-top: 30px; color: #979db1;">
|
||||||
|
©2025 xiaozhi-esp32-server
|
||||||
|
</div>
|
||||||
|
<ModelEditDialog :visible.sync="editDialogVisible" :modelData="editModelData" @save="handleModelSave"/>
|
||||||
|
<TtsModel :visible.sync="ttsDialogVisible" />
|
||||||
|
</el-main>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HeaderBar from "@/components/HeaderBar.vue";
|
||||||
|
import ModelEditDialog from "@/components/ModelEditDialog.vue";
|
||||||
|
import TtsModel from "@/components/TtsModel.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { HeaderBar, ModelEditDialog, TtsModel },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeTab: 'vad',
|
||||||
|
search: '',
|
||||||
|
editDialogVisible: false,
|
||||||
|
editModelData: {},
|
||||||
|
ttsDialogVisible: false,
|
||||||
|
modelList: [
|
||||||
|
{ code: 'AILLM', candidateName: '阿里百炼', isApplied: true, supplier: 'openai' },
|
||||||
|
{ code: 'DoubaoLLM', candidateName: '豆包大模型', isApplied: true, supplier: 'openai' },
|
||||||
|
{ code: 'DeepSeekLLM', candidateName: '深度求索', isApplied: true, supplier: 'openai' },
|
||||||
|
{ code: 'DifyLLM', candidateName: 'DifChat', isApplied: true, supplier: 'dify' },
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 4,
|
||||||
|
total: 20
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 查询
|
||||||
|
handleSearch() {
|
||||||
|
console.log('查询:', this.search);
|
||||||
|
},
|
||||||
|
// 批量删除
|
||||||
|
batchDelete() {
|
||||||
|
console.log('批量删除');
|
||||||
|
},
|
||||||
|
// 增加
|
||||||
|
addModel() {
|
||||||
|
console.log('增加模型');
|
||||||
|
},
|
||||||
|
// 修改
|
||||||
|
editModel(model) {
|
||||||
|
this.editModelData = {
|
||||||
|
code: model.code,
|
||||||
|
name: model.candidateName,
|
||||||
|
supplier: model.supplier,
|
||||||
|
};
|
||||||
|
this.editDialogVisible = true;
|
||||||
|
},
|
||||||
|
// 删除
|
||||||
|
deleteModel(model) {
|
||||||
|
console.log('删除:', model);
|
||||||
|
},
|
||||||
|
handleCurrentChange(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
console.log('当前页码:', page);
|
||||||
|
},
|
||||||
|
// 导入导出
|
||||||
|
handleImportExport() {
|
||||||
|
console.log('导入导出');
|
||||||
|
},
|
||||||
|
handleModelSave(formData) {
|
||||||
|
// 处理保存
|
||||||
|
console.log('保存的模型数据:', formData);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.welcome {
|
||||||
|
min-width: 900px;
|
||||||
|
min-height: 506px;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-image: url("@/assets/home/background.png");
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-search-operate {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-search-operate > * {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table__header th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-tabs-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-tabs {
|
||||||
|
flex-grow: 0;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-export-btn {
|
||||||
|
margin-right: 40px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-tabs {
|
||||||
|
margin-left: 70px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<div class="welcome">
|
||||||
|
<HeaderBar />
|
||||||
|
<el-main style="padding: 20px; display: flex; flex-direction: column;">
|
||||||
|
<el-card class="user-card" shadow="always" >
|
||||||
|
<div class="user-search-operate" style="display: flex; align-items: center; margin-bottom: 20px;">
|
||||||
|
<el-input placeholder="请输入手机号码查询" v-model="searchPhone" style="width: 300px; margin-right: 10px" />
|
||||||
|
<el-button @click="handleSearch">查询</el-button>
|
||||||
|
<el-button type="danger" @click="batchDelete">批量删除</el-button>
|
||||||
|
<el-button type="danger" @click="batchDisable">批量禁用</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="userList" style="width: 100%;" border stripe>
|
||||||
|
<el-table-column label="用户Id" prop="userId"></el-table-column>
|
||||||
|
<el-table-column label="手机号码" prop="phone"></el-table-column>
|
||||||
|
<el-table-column label="Status" prop="status"></el-table-column>
|
||||||
|
<el-table-column label="设备数量" prop="deviceCount"></el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button size="mini" @click="resetPassword(scope.row)">重置密码</el-button>
|
||||||
|
<el-button size="mini"
|
||||||
|
v-if="scope.row.status === '正常'"
|
||||||
|
@click="disableUser(scope.row)">禁用</el-button>
|
||||||
|
<el-button size="mini"
|
||||||
|
v-if="scope.row.status === '禁用'"
|
||||||
|
@click="restoreUser(scope.row)">恢复</el-button>
|
||||||
|
<el-button size="mini" @click="deleteUser(scope.row)" style="color: #ff4949">删除用户</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-sizes="[5, 10, 15]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="prev, pager, next"
|
||||||
|
:total="total"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="font-size: 12px; font-weight: 400; margin-top: auto; padding-top: 30px; color: #979db1;">
|
||||||
|
©2025 xiaozhi-esp32-server
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HeaderBar from "@/components/HeaderBar.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { HeaderBar },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchPhone: '',
|
||||||
|
userList: [
|
||||||
|
{ userId: '123456', phone: '13800138000', status: '正常', deviceCount: 10 },
|
||||||
|
{ userId: '123456', phone: '13800138000', status: '正常', deviceCount: 9 },
|
||||||
|
{ userId: '123456', phone: '13800138000', status: '正常', deviceCount: 7 },
|
||||||
|
{ userId: '123456', phone: '13800138000', status: '禁用', deviceCount: 7 }
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 4,
|
||||||
|
total: 20
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSearch() {
|
||||||
|
// 模拟搜索逻辑
|
||||||
|
console.log('执行查询,搜索号码:', this.searchPhone);
|
||||||
|
},
|
||||||
|
batchDelete() {
|
||||||
|
console.log('执行批量删除操作');
|
||||||
|
},
|
||||||
|
batchDisable() {
|
||||||
|
console.log('执行批量禁用操作');
|
||||||
|
},
|
||||||
|
resetPassword(row) {
|
||||||
|
console.log('重置用户密码,用户:', row);
|
||||||
|
},
|
||||||
|
disableUser(row) {
|
||||||
|
row.status = '禁用';
|
||||||
|
console.log('禁用用户:', row);
|
||||||
|
},
|
||||||
|
restoreUser(row) {
|
||||||
|
row.status = '正常';
|
||||||
|
console.log('恢复用户:', row);
|
||||||
|
},
|
||||||
|
deleteUser(row) {
|
||||||
|
console.log('删除用户:', row);
|
||||||
|
},
|
||||||
|
handleCurrentChange(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
console.log('当前页码:', page);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.welcome {
|
||||||
|
min-width: 900px;
|
||||||
|
min-height: 506px;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-image: url("@/assets/home/background.png");
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-search-operate {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-search-operate > * {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table__header th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -125,11 +125,11 @@ export default {
|
|||||||
],
|
],
|
||||||
models: [
|
models: [
|
||||||
{ label: '大语言模型(LLM)', key: 'llm' },
|
{ label: '大语言模型(LLM)', key: 'llm' },
|
||||||
{ label: '语音转文本模型(ASR)', key: 'asr' },
|
{ label: '语音识别(ASR)', key: 'asr' },
|
||||||
{ label: '语音活动检测模型(VAD)', key: 'vad' },
|
{ label: '语音活动检测模型(VAD)', key: 'vad' },
|
||||||
{ label: '语音生成模型(TTS)', key: 'tts' },
|
{ label: '语音合成模型(TTS)', key: 'tts' },
|
||||||
{ label: '意图分类模型(Intent)', key: 'intent' },
|
{ label: '意图识别模型(Intent)', key: 'intent' },
|
||||||
{ label: '记忆增强模型(Memory)', key: 'memory' }
|
{ label: '记忆模型(Memory)', key: 'memory' }
|
||||||
],
|
],
|
||||||
templates: ['台湾女友', '土豆子', '英语老师', '好奇小男孩', '汪汪队队长']
|
templates: ['台湾女友', '土豆子', '英语老师', '好奇小男孩', '汪汪队队长']
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,13 @@ plugins:
|
|||||||
- 卧室,台灯,switch.iot_cn_831898993_socn1_on_p_2_1
|
- 卧室,台灯,switch.iot_cn_831898993_socn1_on_p_2_1
|
||||||
base_url: http://homeassistant.local:8123
|
base_url: http://homeassistant.local:8123
|
||||||
api_key: 你的home assistant api访问令牌
|
api_key: 你的home assistant api访问令牌
|
||||||
|
play_music:
|
||||||
|
music_dir: "./music" # 音乐文件存放路径,将从该目录及子目录下搜索音乐文件
|
||||||
|
music_ext: # 音乐文件类型,p3格式效率最高
|
||||||
|
- ".mp3"
|
||||||
|
- ".wav"
|
||||||
|
- ".p3"
|
||||||
|
refresh_time: 300 # 刷新音乐列表的时间间隔,单位为秒
|
||||||
|
|
||||||
|
|
||||||
Memory:
|
Memory:
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ play_music_function_desc = {
|
|||||||
"type": "function",
|
"type": "function",
|
||||||
"function": {
|
"function": {
|
||||||
"name": "play_music",
|
"name": "play_music",
|
||||||
"description": "唱歌、听歌、播放音乐方法。比如用户说播放音乐,参数为:random,比如用户说播放两只老虎,参数为:两只老虎",
|
"description": "唱歌、听歌、播放音乐的方法。",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"song_name": {
|
"song_name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "歌曲名称,如果没有指定具体歌名则为'random'"
|
"description": "歌曲名称,如果用户没有指定具体歌名则为'random', 明确指定的时返回音乐的名字 示例: ```用户:播放两只老虎\n参数:两只老虎``` ```用户:播放音乐 \n参数:random ```"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["song_name"]
|
"required": ["song_name"]
|
||||||
@@ -112,8 +112,8 @@ def get_music_files(music_dir, music_ext):
|
|||||||
def initialize_music_handler(conn):
|
def initialize_music_handler(conn):
|
||||||
global MUSIC_CACHE
|
global MUSIC_CACHE
|
||||||
if MUSIC_CACHE == {}:
|
if MUSIC_CACHE == {}:
|
||||||
if "music" in conn.config:
|
if "play_music" in conn.config["plugins"]:
|
||||||
MUSIC_CACHE["music_config"] = conn.config["music"]
|
MUSIC_CACHE["music_config"] = conn.config["plugins"]["play_music"]
|
||||||
MUSIC_CACHE["music_dir"] = os.path.abspath(
|
MUSIC_CACHE["music_dir"] = os.path.abspath(
|
||||||
MUSIC_CACHE["music_config"].get("music_dir", "./music") # 默认路径修改
|
MUSIC_CACHE["music_config"].get("music_dir", "./music") # 默认路径修改
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user