Files
xiaozhi-esp32-server/main/manager-web/src/components/DeviceItem.vue
T

159 lines
4.4 KiB
Vue
Raw Normal View History

2025-03-14 23:48:59 +08:00
<template>
<div class="device-item">
<div style="display: flex;justify-content: space-between;">
2025-03-19 18:13:03 +08:00
<div style="font-weight: 700;font-size: 18px;text-align: left;color: #3d4566;">
2025-04-06 18:28:39 +08:00
{{ device.agentName }}
2025-03-14 23:48:59 +08:00
</div>
<div>
2025-04-06 18:28:39 +08:00
<img src="@/assets/home/delete.png" alt="" style="width: 18px;height: 18px;margin-right: 10px;"
@click.stop="handleDelete" />
<el-tooltip class="item" effect="dark" :content="device.systemPrompt" placement="top"
popper-class="custom-tooltip">
<img src="@/assets/home/info.png" alt="" style="width: 18px;height: 18px;" />
</el-tooltip>
2025-03-14 23:48:59 +08:00
</div>
</div>
<div class="device-name">
{{ $t('home.languageModel') }}{{ device.llmModelName }}
2025-03-14 23:48:59 +08:00
</div>
2025-03-18 21:49:57 +08:00
<div class="device-name">
{{ $t('home.voiceModel') }}{{ device.ttsModelName }} ({{ device.ttsVoiceName }})
2025-03-18 21:49:57 +08:00
</div>
2025-03-14 23:48:59 +08:00
<div style="display: flex;gap: 10px;align-items: center;">
2025-09-12 18:09:09 +08:00
<div class="settings-btn" @click="handleConfigure">
{{ $t('home.configureRole') }}
</div>
2025-12-05 14:35:53 +08:00
<div v-if="featureStatus.voiceprintRecognition" class="settings-btn" @click="handleVoicePrint">
{{ $t('home.voiceprintRecognition') }}
2025-03-14 23:48:59 +08:00
</div>
2025-09-12 18:09:09 +08:00
<div class="settings-btn" @click="handleDeviceManage">
{{ $t('home.deviceManagement') }}({{ device.deviceCount }})
2025-03-18 21:49:57 +08:00
</div>
2025-09-12 18:09:09 +08:00
<div :class="['settings-btn', { 'disabled-btn': device.memModelId === 'Memory_nomem' }]"
@click="handleChatHistory">
<el-tooltip v-if="device.memModelId === 'Memory_nomem'" :content="$t('home.enableMemory')" placement="top">
<span>{{ $t('home.chatHistory') }}</span>
</el-tooltip>
<span v-else>{{ $t('home.chatHistory') }}</span>
2025-05-04 12:53:36 +08:00
</div>
2025-03-14 23:48:59 +08:00
</div>
<div class="version-info">
<div>{{ $t('home.lastConversation') }}{{ formattedLastConnectedTime }}</div>
2025-03-14 23:48:59 +08:00
</div>
</div>
</template>
<script>
import i18n from '@/i18n';
2025-03-14 23:48:59 +08:00
export default {
name: 'DeviceItem',
props: {
2025-12-05 14:35:53 +08:00
device: { type: Object, required: true },
featureStatus: {
type: Object,
default: () => ({
voiceprintRecognition: false,
voiceClone: false,
knowledgeBase: false
})
}
2025-03-14 23:48:59 +08:00
},
data() {
return { switchValue: false }
2025-03-24 09:16:48 +08:00
},
2025-05-07 22:56:51 +08:00
computed: {
formattedLastConnectedTime() {
if (!this.device.lastConnectedAt) return this.$t('home.noConversation');
2025-05-07 22:56:51 +08:00
const lastTime = new Date(this.device.lastConnectedAt);
const now = new Date();
const diffMinutes = Math.floor((now - lastTime) / (1000 * 60));
2025-05-07 23:21:47 +08:00
if (diffMinutes <= 1) {
return this.$t('home.justNow');
2025-05-07 23:21:47 +08:00
} else if (diffMinutes < 60) {
return this.$t('home.minutesAgo', { minutes: diffMinutes });
2025-05-07 22:56:51 +08:00
} else if (diffMinutes < 24 * 60) {
const hours = Math.floor(diffMinutes / 60);
const minutes = diffMinutes % 60;
return this.$t('home.hoursAgo', { hours, minutes });
2025-05-07 22:56:51 +08:00
} else {
return this.device.lastConnectedAt;
}
}
},
2025-03-24 09:16:48 +08:00
methods: {
handleDelete() {
this.$emit('delete', this.device.agentId)
2025-03-24 17:27:08 +08:00
},
handleConfigure() {
this.$router.push({ path: '/role-config', query: { agentId: this.device.agentId } });
2025-03-25 16:23:28 +08:00
},
handleVoicePrint() {
this.$router.push({ path: '/voice-print', query: { agentId: this.device.agentId } });
},
2025-03-25 16:23:28 +08:00
handleDeviceManage() {
this.$router.push({ path: '/device-management', query: { agentId: this.device.agentId } });
2025-05-04 12:53:36 +08:00
},
handleChatHistory() {
if (this.device.memModelId === 'Memory_nomem') {
return
}
2025-05-04 12:53:36 +08:00
this.$emit('chat-history', { agentId: this.device.agentId, agentName: this.device.agentName })
2025-03-24 09:16:48 +08:00
}
2025-03-14 23:48:59 +08:00
}
}
</script>
<style scoped>
.device-item {
2025-03-18 21:49:57 +08:00
width: 342px;
2025-03-14 23:48:59 +08:00
border-radius: 20px;
background: #fafcfe;
2025-03-18 21:49:57 +08:00
padding: 22px;
2025-03-14 23:48:59 +08:00
box-sizing: border-box;
}
2025-04-06 18:28:39 +08:00
2025-03-14 23:48:59 +08:00
.device-name {
2025-03-18 21:49:57 +08:00
margin: 7px 0 10px;
2025-03-14 23:48:59 +08:00
font-weight: 400;
2025-03-19 18:13:03 +08:00
font-size: 11px;
2025-03-14 23:48:59 +08:00
color: #3d4566;
text-align: left;
}
.settings-btn {
font-weight: 500;
font-size: 12px;
2025-03-14 23:48:59 +08:00
color: #5778ff;
background: #e6ebff;
2025-04-16 12:55:07 +08:00
width: auto;
padding: 0 12px;
2025-03-18 21:49:57 +08:00
height: 21px;
line-height: 21px;
2025-03-14 23:48:59 +08:00
cursor: pointer;
border-radius: 14px;
}
.version-info {
display: flex;
justify-content: space-between;
2025-03-18 21:49:57 +08:00
margin-top: 15px;
font-size: 12px;
2025-03-14 23:48:59 +08:00
color: #979db1;
font-weight: 400;
}
.disabled-btn {
background: #e6e6e6;
color: #999;
cursor: not-allowed;
}
2025-04-06 18:28:39 +08:00
</style>
2025-03-18 21:49:57 +08:00
2025-04-06 18:28:39 +08:00
<style>
.custom-tooltip {
max-width: 400px;
word-break: break-word;
}
2025-03-14 23:48:59 +08:00
</style>