mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 15:13:55 +08:00
update:设置接口读取方式
This commit is contained in:
@@ -1 +1,4 @@
|
||||
VUE_APP_API_BASE_URL=https://2662r3426b.vicp.fun
|
||||
# 暂时使用群主的接口
|
||||
VUE_APP_API_BASE_URL=https://2662r3426b.vicp.fun/xiaozhi-esp32-api
|
||||
# 如果本地开发,请使用以下接口
|
||||
# VUE_APP_API_BASE_URL=http://localhost:8002/xiaozhi-esp32-api
|
||||
@@ -1 +1 @@
|
||||
VUE_APP_API_BASE_URL=https://2662r3426b.vicp.fun
|
||||
VUE_APP_API_BASE_URL=/xiaozhi-esp32-api
|
||||
@@ -1,22 +1,17 @@
|
||||
// 引入各个模块的请求
|
||||
import user from './module/user.js'
|
||||
import admin from './module/admin.js'
|
||||
/**
|
||||
* 接口地址
|
||||
* 当前8002端口接口还没开发完成,暂时用 apifoxmock 接口代替
|
||||
* 如果你想调用8002端口,就用'/xiaozhi-esp32-api/api/v1',请与vue.config.js的devServer配置相结合,方便跨域请求
|
||||
*
|
||||
* 开发时自动读取使用.env.development文件
|
||||
* 编译时自动读取使用.env.production文件
|
||||
*/
|
||||
const DEV_API_SERVICE = 'https://2662r3426b.vicp.fun/xiaozhi-esp32-api'
|
||||
// 8002开发完成完成后使用这个
|
||||
// const DEV_API_SERVICE = '/xiaozhi-esp32-api'
|
||||
const DEV_API_SERVICE = process.env.VUE_APP_API_BASE_URL
|
||||
|
||||
/**
|
||||
* 根据开发环境返回接口url
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getServiceUrl() {
|
||||
// return '/xiaozhi-esp32-api'
|
||||
return DEV_API_SERVICE
|
||||
}
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
<img loading="lazy" alt="" src="@/assets/header/robot.png" :style="{ filter: $route.path === '/home' ? 'brightness(0) invert(1)' : 'None' }"/>
|
||||
智能体管理
|
||||
</div>
|
||||
<div v-if="isSuperAdmin" class="equipment-management" :class="{ 'active-tab': $route.path === '/user-management' }" @click="goUserManagement">
|
||||
<img loading="lazy" alt="" src="@/assets/header/user_management.png" :style="{ filter: $route.path === '/user-management' ? 'brightness(0) invert(1)' : 'None' }"/>
|
||||
用户管理
|
||||
</div>
|
||||
<div v-if="isSuperAdmin" class="equipment-management" :class="{ 'active-tab': $route.path === '/model-config' }" @click="goModelConfig">
|
||||
<img loading="lazy" alt="" src="@/assets/header/model_config.png" :style="{ filter: $route.path === '/model-config' ? 'brightness(0) invert(1)' : 'None' }"/>
|
||||
模型配置
|
||||
</div>
|
||||
<div v-if="isSuperAdmin" class="equipment-management" :class="{ 'active-tab': $route.path === '/user-management' }" @click="goUserManagement">
|
||||
<img loading="lazy" alt="" src="@/assets/header/user_management.png" :style="{ filter: $route.path === '/user-management' ? 'brightness(0) invert(1)' : 'None' }"/>
|
||||
用户管理
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧元素 -->
|
||||
@@ -41,9 +41,8 @@
|
||||
{{ userInfo.username || '加载中...' }}<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-plus" @click.native="">个人中心</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-circle-plus" @click.native="showChangePasswordDialog">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-circle-plus-outline" @click.native="handleLogout">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="showChangePasswordDialog">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="handleLogout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
@@ -56,8 +55,8 @@
|
||||
|
||||
<script>
|
||||
import userApi from '@/apis/module/user';
|
||||
import ChangePasswordDialog from './ChangePasswordDialog.vue'; // 引入修改密码弹窗组件
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
import ChangePasswordDialog from './ChangePasswordDialog.vue'; // 引入修改密码弹窗组件
|
||||
|
||||
|
||||
export default {
|
||||
@@ -187,8 +186,7 @@ export default {
|
||||
}
|
||||
|
||||
.brand-img {
|
||||
width: 58px;
|
||||
height: 12px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.header-center {
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
<el-table-column label="最近对话" prop="lastConversation" width="140"></el-table-column>
|
||||
<el-table-column label="备注" width="180">
|
||||
<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>
|
||||
<i v-if="!scope.row.remark" class="el-icon-edit" @click="startEditRemark(scope.$index, scope.row)"></i>
|
||||
<span v-else @click="startEditRemark(scope.$index, scope.row)">
|
||||
@@ -26,7 +27,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="OTA升级" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="scope.row.otaSwitch" size="mini" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
|
||||
<el-switch v-model="scope.row.otaSwitch" size="mini" active-color="#13ce66"
|
||||
inactive-color="#ff4949"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
@@ -37,31 +39,25 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
class="pagination"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="deviceList.length"
|
||||
></el-pagination>
|
||||
<el-pagination class="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
:current-page="currentPage" :page-sizes="[5, 10, 20, 50]" :page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="deviceList.length"></el-pagination>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
©2025 xiaozhi-esp32-server
|
||||
</div>
|
||||
<AddDeviceDialog :visible.sync="addDeviceDialogVisible" :agent-id="currentAgentId" @refresh="fetchBindDevices(currentAgentId)" />
|
||||
<AddDeviceDialog :visible.sync="addDeviceDialogVisible" :agent-id="currentAgentId"
|
||||
@refresh="fetchBindDevices(currentAgentId)" />
|
||||
</el-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HeaderBar from "@/components/HeaderBar.vue";
|
||||
import AddDeviceDialog from "@/components/AddDeviceDialog.vue";
|
||||
import HeaderBar from "@/components/HeaderBar.vue";
|
||||
|
||||
export default {
|
||||
components: {HeaderBar, AddDeviceDialog },
|
||||
components: { HeaderBar, AddDeviceDialog },
|
||||
data() {
|
||||
return {
|
||||
addDeviceDialogVisible: false,
|
||||
@@ -112,14 +108,14 @@ export default {
|
||||
this.deviceApi.unbindDevice(device_id, ({ data }) => {
|
||||
if (data.code === 0) {
|
||||
this.$message.success({
|
||||
message: '设备解绑成功',
|
||||
showClose: true
|
||||
message: '设备解绑成功',
|
||||
showClose: true
|
||||
});
|
||||
this.fetchBindDevices(this.$route.query.agentId);
|
||||
} else {
|
||||
this.$message.error({
|
||||
message: data.msg || '设备解绑失败',
|
||||
showClose: true
|
||||
message: data.msg || '设备解绑失败',
|
||||
showClose: true
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -141,7 +137,7 @@ export default {
|
||||
this.deviceList = data.data.map(device => {
|
||||
// 格式化绑定时间
|
||||
const bindDate = new Date(device.createDate);
|
||||
const formattedBindTime = `${bindDate.getFullYear()}-${(bindDate.getMonth()+1).toString().padStart(2, '0')}-${bindDate.getDate().toString().padStart(2, '0')} ${bindDate.getHours().toString().padStart(2, '0')}:${bindDate.getMinutes().toString().padStart(2, '0')}:${bindDate.getSeconds().toString().padStart(2, '0')}`;
|
||||
const formattedBindTime = `${bindDate.getFullYear()}-${(bindDate.getMonth() + 1).toString().padStart(2, '0')}-${bindDate.getDate().toString().padStart(2, '0')} ${bindDate.getHours().toString().padStart(2, '0')}:${bindDate.getMinutes().toString().padStart(2, '0')}:${bindDate.getSeconds().toString().padStart(2, '0')}`;
|
||||
return {
|
||||
device_id: device.id,
|
||||
model: device.board,
|
||||
@@ -156,8 +152,8 @@ export default {
|
||||
rawBindTime: new Date(device.createDate).getTime()
|
||||
};
|
||||
})
|
||||
// 按照绑定时间降序排序
|
||||
.sort((a, b) => a.rawBindTime - b.rawBindTime);
|
||||
// 按照绑定时间降序排序
|
||||
.sort((a, b) => a.rawBindTime - b.rawBindTime);
|
||||
} else {
|
||||
this.$message.error(data.msg || '获取设备列表失败');
|
||||
}
|
||||
@@ -207,6 +203,7 @@ export default {
|
||||
font-size: 14px;
|
||||
gap: 8px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
&:hover {
|
||||
background: #3a8ee6;
|
||||
}
|
||||
|
||||
@@ -1,55 +1,52 @@
|
||||
<template>
|
||||
<div class="welcome">
|
||||
<!-- 公共头部 -->
|
||||
<HeaderBar :devices="devices" @search="handleSearch" @search-reset="handleSearchReset" />
|
||||
<el-main style="padding: 20px;display: flex;flex-direction: column;">
|
||||
<div>
|
||||
<!-- 首页内容 -->
|
||||
<div class="add-device">
|
||||
<div class="add-device-bg">
|
||||
<div class="hellow-text" style="margin-top: 30px;">
|
||||
您好,小智
|
||||
<!-- 公共头部 -->
|
||||
<HeaderBar :devices="devices" @search="handleSearch" @search-reset="handleSearchReset" />
|
||||
<el-main style="padding: 20px;display: flex;flex-direction: column;">
|
||||
<div>
|
||||
<!-- 首页内容 -->
|
||||
<div class="add-device">
|
||||
<div class="add-device-bg">
|
||||
<div class="hellow-text" style="margin-top: 30px;">
|
||||
你好,小智
|
||||
</div>
|
||||
<div class="hellow-text">
|
||||
让我们度过
|
||||
<div style="display: inline-block;color: #5778FF;">
|
||||
美好的一天!
|
||||
</div>
|
||||
<div class="hellow-text">
|
||||
让我们度过
|
||||
<div style="display: inline-block;color: #5778FF;">
|
||||
美好的一天!
|
||||
</div>
|
||||
</div>
|
||||
<div class="hi-hint">
|
||||
Hello, Let's have a wonderful day!
|
||||
</div>
|
||||
<div class="add-device-btn" @click="showAddDialog">
|
||||
<div class="left-add">
|
||||
添加智能体
|
||||
</div>
|
||||
<div class="hi-hint">
|
||||
Hello, Let's have a wonderful day!
|
||||
</div>
|
||||
<div class="add-device-btn" @click="showAddDialog">
|
||||
<div class="left-add">
|
||||
添加智能体
|
||||
</div>
|
||||
<div style="width: 23px;height: 13px;background: #5778ff;margin-left: -10px;" />
|
||||
<div class="right-add">
|
||||
<i class="el-icon-right" style="font-size: 20px;color: #fff;" />
|
||||
</div>
|
||||
<div style="width: 23px;height: 13px;background: #5778ff;margin-left: -10px;" />
|
||||
<div class="right-add">
|
||||
<i class="el-icon-right" style="font-size: 20px;color: #fff;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device-list-container">
|
||||
<DeviceItem v-for="(item,index) in devices" :key="index" :device="item"
|
||||
@configure="goToRoleConfig"
|
||||
@deviceManage="handleDeviceManage"
|
||||
@delete="handleDeleteAgent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
©2025 xiaozhi-esp32-server
|
||||
<div class="device-list-container">
|
||||
<DeviceItem v-for="(item, index) in devices" :key="index" :device="item" @configure="goToRoleConfig"
|
||||
@deviceManage="handleDeviceManage" @delete="handleDeleteAgent" />
|
||||
</div>
|
||||
<AddWisdomBodyDialog :visible.sync="addDeviceDialogVisible" @confirm="handleWisdomBodyAdded" />
|
||||
</el-main>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
©2025 xiaozhi-esp32-server
|
||||
</div>
|
||||
<AddWisdomBodyDialog :visible.sync="addDeviceDialogVisible" @confirm="handleWisdomBodyAdded" />
|
||||
</el-main>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeviceItem from '@/components/DeviceItem.vue'
|
||||
import AddWisdomBodyDialog from '@/components/AddWisdomBodyDialog.vue'
|
||||
import DeviceItem from '@/components/DeviceItem.vue'
|
||||
import HeaderBar from '@/components/HeaderBar.vue'
|
||||
|
||||
export default {
|
||||
@@ -112,7 +109,7 @@ export default {
|
||||
// 获取智能体列表
|
||||
fetchAgentList() {
|
||||
import('@/apis/module/agent').then(({ default: userApi }) => {
|
||||
userApi.getAgentList(({data}) => {
|
||||
userApi.getAgentList(({ data }) => {
|
||||
this.originalDevices = data.data.map(item => ({
|
||||
...item,
|
||||
agentId: item.id // 字段映射
|
||||
@@ -132,19 +129,19 @@ export default {
|
||||
userApi.deleteAgent(agentId, (res) => {
|
||||
if (res.data.code === 0) {
|
||||
this.$message.success({
|
||||
message: '删除成功',
|
||||
showClose: true
|
||||
message: '删除成功',
|
||||
showClose: true
|
||||
});
|
||||
this.fetchAgentList(); // 刷新列表
|
||||
} else {
|
||||
this.$message.error({
|
||||
message: res.data.msg || '删除失败',
|
||||
showClose: true
|
||||
message: res.data.msg || '删除失败',
|
||||
showClose: true
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,18 +164,18 @@ export default {
|
||||
-o-background-size: cover;
|
||||
/* 兼容老版本Opera浏览器 */
|
||||
}
|
||||
|
||||
.add-device {
|
||||
height: 195px;
|
||||
border-radius: 15px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(
|
||||
269.62deg,
|
||||
background: linear-gradient(269.62deg,
|
||||
#e0e6fd 0%,
|
||||
#cce7ff 49.69%,
|
||||
#d3d3fe 100%
|
||||
);
|
||||
#d3d3fe 100%);
|
||||
}
|
||||
|
||||
.add-device-bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -193,6 +190,7 @@ export default {
|
||||
/* 兼容老版本WebKit浏览器 */
|
||||
-o-background-size: cover;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* 兼容老版本Opera浏览器 */
|
||||
.hellow-text {
|
||||
margin-left: 75px;
|
||||
@@ -252,7 +250,8 @@ export default {
|
||||
|
||||
/* 在 DeviceItem.vue 的样式中 */
|
||||
.device-item {
|
||||
margin: 0 !important; /* 避免冲突 */
|
||||
margin: 0 !important;
|
||||
/* 避免冲突 */
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
@@ -262,7 +261,7 @@ export default {
|
||||
margin-top: auto;
|
||||
padding-top: 30px;
|
||||
color: #979db1;
|
||||
text-align: center; /* 居中显示 */
|
||||
text-align: center;
|
||||
/* 居中显示 */
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -5,7 +5,7 @@
|
||||
<div
|
||||
style="display: flex;align-items: center;margin-top: 15px;margin-left: 10px;gap: 10px;">
|
||||
<img loading="lazy" alt="" src="@/assets/xiaozhi-logo.png" style="width: 45px;height: 45px;"/>
|
||||
<img loading="lazy" alt="" src="@/assets/xiaozhi-ai.png" style="width: 70px;height: 13px;"/>
|
||||
<img loading="lazy" alt="" src="@/assets/xiaozhi-ai.png" style="height: 18px;"/>
|
||||
</div>
|
||||
</el-header>
|
||||
<div class="login-person">
|
||||
@@ -66,8 +66,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUUID, goToPage, showDanger, showSuccess} from '@/utils'
|
||||
import Api from '@/apis/api';
|
||||
import { getUUID, goToPage, showDanger, showSuccess } from '@/utils';
|
||||
|
||||
|
||||
export default {
|
||||
|
||||
@@ -15,20 +15,13 @@ module.exports = defineConfig({
|
||||
devServer: {
|
||||
port: 8001, // 指定端口为 8001
|
||||
proxy: {
|
||||
'/xiaozhi-esp32-api': {
|
||||
target: process.env.VUE_APP_API_BASE_URL, // 后端 API 的基础 URL
|
||||
changeOrigin: true, // 允许跨域
|
||||
pathRewrite: {
|
||||
'^/xiaozhi-esp32-api': '/xiaozhi-esp32-api',
|
||||
},
|
||||
},
|
||||
},
|
||||
client: {
|
||||
overlay: false, // 不显示 webpack 错误覆盖层
|
||||
},
|
||||
},
|
||||
chainWebpack: config => {
|
||||
|
||||
|
||||
// 修改 HTML 插件配置,动态插入 CDN 链接
|
||||
config.plugin('html')
|
||||
.tap(args => {
|
||||
@@ -50,7 +43,7 @@ module.exports = defineConfig({
|
||||
}
|
||||
return args;
|
||||
});
|
||||
|
||||
|
||||
// 代码分割优化
|
||||
config.optimization.splitChunks({
|
||||
chunks: 'all',
|
||||
@@ -72,12 +65,12 @@ module.exports = defineConfig({
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 启用优化设置
|
||||
config.optimization.usedExports(true);
|
||||
config.optimization.concatenateModules(true);
|
||||
config.optimization.minimize(true);
|
||||
},
|
||||
},
|
||||
configureWebpack: config => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// 开启多线程编译
|
||||
|
||||
Reference in New Issue
Block a user