Skip to content
Snippets Groups Projects
Commit ad39355c authored by LiuYanchen's avatar LiuYanchen
Browse files

fix

parent 9478bf11
Branches main
No related tags found
No related merge requests found
Pipeline #172082 failed
# music
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
# run unit tests
npm run unit
# run e2e tests
npm run e2e
# run all tests
npm test
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
......@@ -12,7 +12,8 @@ module.exports = {
assetsPublicPath: '/',
// Various Dev Server settings
host: '172.29.4.184', // can be overwritten by process.env.HOST
// host: '172.29.4.184', // can be overwritten by process.env.HOST
host: 'localhost', // can be overwritten by process.env.HOST
port: 5173, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
......
This diff is collapsed.
This diff is collapsed.
const BACKURL = 'http://172.29.4.184:8080'
// const BACKURL = 'http://172.29.4.184:8080'
const BACKURL = 'http://localhost:8080'
export default BACKURL
......@@ -2,6 +2,11 @@
<div class="chat-box">
<div class="chat-header">
<h3>畅听 - AI音乐助手</h3>
<p style="font-size: 12px; line-height: 1.5;">
今日对话次数:{{ statistics.daily }}<br>
总计对话次数:{{ statistics.total }}
</p>
<button class="close-btn" @click="$emit('close')">×</button>
</div>
<div class="chat-body">
......@@ -41,17 +46,33 @@ export default {
setup() {
const messages = ref([]); // 对话消息数组
const userInput = ref(""); // 用户输入
const statistics = ref({
total: 0,
daily: 0
});
// 用户和助手头像
const userAvatar = require("@/assets/img/img.png");
const botAvatar = require("@/assets/img/img.png");
const fetchStatistics = async () => {
try {
const response = await fetch('http://localhost:8080/api/chat/statistics');
const data = await response.json();
statistics.value = data;
} catch (error) {
console.error('Error fetching statistics:', error);
}
};
// 页面加载时 AI 自动发送欢迎消息
onMounted(() => {
messages.value.push({
text: "你好,我是畅听 AI 音乐助手,有什么可以帮您的吗?",
isUser: false,
});
fetchStatistics();
setInterval(fetchStatistics, 60000);
});
const sendMessage = () => {
......@@ -61,7 +82,8 @@ export default {
messages.value.push({ text: userInput.value, isUser: true });
// 调用后端 API
fetch(`http://172.29.4.184:8080/api/chat`, {
// fetch(`http://172.29.4.184:8080/api/chat`, {
fetch(`http://localhost:8080/api/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: userInput.value }),
......@@ -73,6 +95,7 @@ export default {
text: data.reply || "抱歉,我无法理解您的请求。",
isUser: false,
});
fetchStatistics();
})
.catch((error) => {
console.error("Error:", error);
......@@ -92,6 +115,7 @@ export default {
sendMessage,
userAvatar,
botAvatar,
statistics,
};
},
};
......
......@@ -21,12 +21,29 @@
</li>
<li>
<div class="head-search">
<input
type="text"
placeholder="搜索音乐"
@keyup.enter="goSearch()"
v-model="keywords"
/>
<div class="search-input-wrapper">
<input
type="text"
placeholder="搜索音乐"
@keyup.enter="goSearch()"
@focus="showHistory"
v-model="keywords"
/>
<div class="search-history" v-show="isShowHistory && loginIn">
<div class="history-header">
<span>搜索历史</span>
<span class="clear-history" @click.stop="clearHistory">清除</span>
</div>
<ul class="history-list" v-if="searchHistory.length">
<li v-for="(item, index) in searchHistory"
:key="index"
@click.stop="searchByHistory(item)">
{{ item }}
</li>
</ul>
<div v-else class="no-history">暂无搜索记录</div>
</div>
</div>
<div class="search-btn" @click="goSearch()">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-sousuo"></use>
......@@ -66,6 +83,9 @@
import { mixin } from '../mixins'
import { mapGetters } from 'vuex'
import { navMsg, loginMsg, menuList } from '../assets/data/header'
import axios from 'axios'
import BACKURL from '../api/backConfig'
const host = BACKURL
export default {
name: 'the-header',
......@@ -76,7 +96,9 @@ export default {
navMsg: [], // 左侧导航栏
loginMsg: [], // 右侧导航栏
menuList: [], // 用户下拉菜单项
keywords: ''
keywords: '',
searchHistory: [],
isShowHistory: false
}
},
computed: {
......@@ -137,9 +159,89 @@ export default {
}
},
goSearch() {
this.$store.commit('setSearchword', this.keywords)
this.$router.push({ path: '/search', query: { keywords: this.keywords } })
if (!this.keywords.trim()) return;
if (this.loginIn) {
this.addSearchHistory(this.keywords);
}
this.isShowHistory = false;
this.$store.commit('setSearchword', this.keywords);
this.$router.push({ path: '/search', query: { keywords: this.keywords } });
},
// 获取搜索历史
getSearchHistory() {
if (!this.loginIn) return;
axios.get(`${host}/search/history?userId=${this.userId}`)
.then(res => {
if (res.data.code === 1) {
this.searchHistory = res.data.data;
} else {
this.notify(res.data.msg, 'error');
}
})
.catch(err => {
console.error('获取搜索历史失败:', err);
this.notify('获取搜索历史失败', 'error');
});
},
// 添加搜索历史
addSearchHistory(keyword) {
if (!this.loginIn) return;
var params = new URLSearchParams()
params.append('userId', this.userId)
params.append('keyword', keyword)
axios.post(`${host}/search/history/add`, params)
.then(res => {
if (res.data.code !== 1) {
this.notify(res.data.msg, 'error');
}
})
.catch(err => {
console.error('添加搜索历史失败:', err);
this.notify('添加搜索历史失败', 'error');
});
},
// 清除搜索历史
clearHistory() {
if (!this.loginIn) return;
axios.get(`${host}/search/history/delete?userId=${this.userId}`)
.then(res => {
if (res.data.code === 1) {
this.searchHistory = [];
this.notify('清除历史记录成功', 'success');
} else {
this.notify(res.data.msg, 'error');
}
})
.catch(err => {
console.error('清除搜索历史失败:', err);
this.notify('清除搜索历史失败', 'error');
});
},
// 显示历史记录
showHistory() {
if (this.loginIn) {
this.isShowHistory = true;
this.getSearchHistory();
}
},
// 点击历史记录搜索
searchByHistory(keyword) {
this.keywords = keyword;
this.goSearch();
}
},
mounted() {
// 点击其他区域关闭历史记录
document.addEventListener('click', (event) => {
const searchWrapper = this.$el.querySelector('.search-input-wrapper');
if (!searchWrapper.contains(event.target)) {
this.isShowHistory = false;
}
});
}
}
</script>
......@@ -284,4 +386,59 @@ export default {
.show {
display: block;
}
.no-history {
text-align: center;
padding: 20px;
color: #999;
font-size: 14px;
}
.search-history {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: #000;
border: 1px solid #333;
border-radius: 4px;
margin-top: 5px;
padding: 10px 0;
z-index: 1000;
}
.history-header {
display: flex;
justify-content: space-between;
padding: 0 10px;
margin-bottom: 10px;
color: #999;
font-size: 14px;
}
.clear-history {
cursor: pointer;
color: #d43c33;
}
.clear-history:hover {
text-decoration: underline;
}
.history-list {
list-style: none;
padding: 0;
margin: 0;
}
.history-list li {
padding: 8px 15px;
cursor: pointer;
color: #fff;
font-size: 14px;
}
.history-list li:hover {
background-color: #333;
}
</style>
const configure = {
state: {
HOST: 'http://172.29.4.184:8080',
// HOST: 'http://172.29.4.184:8080',
HOST: 'http://localhost:8080',
loginIn: false, // 用户是否登录
searchword: '', // 搜索关键词
showAside: false, // 是否显示侧边栏
......
......@@ -83,7 +83,8 @@ const song = {
picUrl: state => {
let picUrl = state.picUrl
if (!picUrl) {
picUrl = JSON.parse(window.sessionStorage.getItem('picUrl')) || 'http://172.29.4.184:8080/img/tubiao.jpg'
// picUrl = JSON.parse(window.sessionStorage.getItem('picUrl')) || 'http://172.29.4.184:8080/img/tubiao.jpg'
picUrl = JSON.parse(window.sessionStorage.getItem('picUrl')) || 'http://localhost:8080/img/tubiao.jpg'
}
return picUrl
},
......
......@@ -10,7 +10,7 @@ module.exports = {
selenium: {
start_process: true,
server_path: require('selenium-server').path,
host: '172.29.4.146',
host: 'localhost',
port: 4444,
cli_args: {
'webdriver.chrome.driver': require('chromedriver').path
......@@ -20,10 +20,10 @@ module.exports = {
test_settings: {
default: {
selenium_port: 4444,
selenium_host: '172.29.4.146',
selenium_host: 'localhost',
silent: true,
globals: {
devServerURL: 'http://172.29.4.146:' + (process.env.PORT || config.dev.port)
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
}
},
......
......@@ -29,7 +29,7 @@
4</td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const BACKURL = <span class="cstat-no" title="statement not covered" >'http://172.29.4.184:8080'</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const BACKURL = <span class="cstat-no" title="statement not covered" >'http://localhost:8080'</span>
&nbsp;
export default BACKURL
&nbsp;</pre></td></tr>
......
......@@ -145,7 +145,8 @@
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const configure = <span class="cstat-no" title="statement not covered" >{</span>
state: {
HOST: 'http://172.29.4.184:8080',
<!-- HOST: 'http://172.29.4.184:8080',-->
HOST: 'http://localhost:8080',
loginIn: false, // 用户是否登录
searchword: '', // 搜索关键词
showAside: false, // 是否显示侧边栏
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment