page
This commit is contained in:
parent
914313944b
commit
814b4aff36
@ -267,13 +267,21 @@ public class QQMusicClient implements ChannelClient<MusicSearchReq, MusicSearchR
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MusicDownloadRes download(String id) {
|
public MusicDownloadRes download(String id) {
|
||||||
String downloadUrl = String.format(qqMusicProperties.getDownloadBaseUrl(), id);
|
String downloadUrl = String.format(qqMusicProperties.getDownloadBaseUrl1(), id);
|
||||||
QQMusicDownloadRes qqMusicDownloadRes = OkHttpUtil.get(downloadUrl, null, null, new TypeReference<>() {
|
QQMusicDownloadRes qqMusicDownloadRes = OkHttpUtil.get(downloadUrl, null, null, new TypeReference<>() {
|
||||||
});
|
});
|
||||||
|
if (Objects.isNull(qqMusicDownloadRes) || Objects.isNull(qqMusicDownloadRes.getMusicUrlInfo())) {
|
||||||
|
downloadUrl = String.format(qqMusicProperties.getDownloadBaseUrl2(), id);
|
||||||
|
qqMusicDownloadRes = OkHttpUtil.get(downloadUrl, null, null, new TypeReference<>() {
|
||||||
|
});
|
||||||
if (Objects.isNull(qqMusicDownloadRes) || Objects.isNull(qqMusicDownloadRes.getMusicUrlInfo())) {
|
if (Objects.isNull(qqMusicDownloadRes) || Objects.isNull(qqMusicDownloadRes.getMusicUrlInfo())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return download(qqMusicDownloadRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MusicDownloadRes download(QQMusicDownloadRes qqMusicDownloadRes) {
|
||||||
MusicDownloadRes musicDownloadRes = new MusicDownloadRes();
|
MusicDownloadRes musicDownloadRes = new MusicDownloadRes();
|
||||||
musicDownloadRes.setAlbumName(qqMusicDownloadRes.getSong().getAlbum());
|
musicDownloadRes.setAlbumName(qqMusicDownloadRes.getSong().getAlbum());
|
||||||
musicDownloadRes.setArtistName(qqMusicDownloadRes.getSong().getSinger());
|
musicDownloadRes.setArtistName(qqMusicDownloadRes.getSong().getSinger());
|
||||||
|
|||||||
@ -22,7 +22,9 @@ public class QQMusicProperties {
|
|||||||
|
|
||||||
private String albumBaseUrl;
|
private String albumBaseUrl;
|
||||||
|
|
||||||
private String downloadBaseUrl;
|
private String downloadBaseUrl1;
|
||||||
|
|
||||||
|
private String downloadBaseUrl2;
|
||||||
|
|
||||||
private String downloadPath;
|
private String downloadPath;
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,8 @@ baogutang:
|
|||||||
query-base-url: http://117.72.78.133:5175/search?key=%s&pageNo=%d&pageSize=%d&t=%d
|
query-base-url: http://117.72.78.133:5175/search?key=%s&pageNo=%d&pageSize=%d&t=%d
|
||||||
playlist-base-url: http://117.72.78.133:5175/songlist?id=%s
|
playlist-base-url: http://117.72.78.133:5175/songlist?id=%s
|
||||||
album-base-url: http://117.72.78.133:5175/album/songs?albummid=%s
|
album-base-url: http://117.72.78.133:5175/album/songs?albummid=%s
|
||||||
download-base-url: http://117.72.78.133:5176/song?url=https://y.qq.com/n/ryqq/songDetail/%s
|
download-base-url1: http://117.72.78.133:5176/song?url=https://y.qq.com/n/ryqq/songDetail/%s
|
||||||
|
download-base-url2: http://117.72.78.133:5176/song?url=https://u.y.qq.com/n/ryqq/songDetail/%s
|
||||||
download-path: /downloads/music
|
download-path: /downloads/music
|
||||||
# download-path: /Users/nikooh/Desktop/downloads/music
|
# download-path: /Users/nikooh/Desktop/downloads/music
|
||||||
|
|
||||||
|
|||||||
@ -241,8 +241,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 其他样式保持不变 */
|
|
||||||
|
|
||||||
.album-list {
|
.album-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -337,7 +335,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 歌单列表样式 */
|
|
||||||
.playlist-list {
|
.playlist-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -435,13 +432,14 @@
|
|||||||
|
|
||||||
<button class="search-btn" onclick="startSearch()">搜索</button>
|
<button class="search-btn" onclick="startSearch()">搜索</button>
|
||||||
|
|
||||||
<div class="search-result" id="result"></div>
|
<!-- 将下载进度条移动到结果列表上方 -->
|
||||||
<div class="loading" id="loading" style="display: none;">加载中...</div>
|
<div class="search-result" id="result">
|
||||||
|
|
||||||
<div class="progress-container" id="progress-container">
|
<div class="progress-container" id="progress-container">
|
||||||
<p>下载进度:<span id="progress-text">0%</span></p>
|
<p>下载进度:<span id="progress-text">0%</span></p>
|
||||||
<progress id="progress-bar" value="0" max="100"></progress>
|
<progress id="progress-bar" value="0" max="100"></progress>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="loading" id="loading" style="display: none;">加载中...</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -470,7 +468,6 @@
|
|||||||
window.addEventListener('scroll', handleScroll);
|
window.addEventListener('scroll', handleScroll);
|
||||||
displayUsername();
|
displayUsername();
|
||||||
|
|
||||||
// 点击用户名时,切换下拉菜单的显示状态
|
|
||||||
const userInfoDiv = document.getElementById('user-info');
|
const userInfoDiv = document.getElementById('user-info');
|
||||||
const dropdownMenu = document.getElementById('dropdown-menu');
|
const dropdownMenu = document.getElementById('dropdown-menu');
|
||||||
userInfoDiv.addEventListener('click', function (event) {
|
userInfoDiv.addEventListener('click', function (event) {
|
||||||
@ -478,7 +475,6 @@
|
|||||||
dropdownMenu.classList.toggle('visible');
|
dropdownMenu.classList.toggle('visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 点击页面其他部分时,隐藏下拉菜单
|
|
||||||
document.addEventListener('click', function () {
|
document.addEventListener('click', function () {
|
||||||
dropdownMenu.classList.remove('visible');
|
dropdownMenu.classList.remove('visible');
|
||||||
});
|
});
|
||||||
@ -486,7 +482,7 @@
|
|||||||
|
|
||||||
function fetchPlatforms() {
|
function fetchPlatforms() {
|
||||||
fetch('/api/v1/music/common?type=channel', {
|
fetch('/api/v1/music/common?type=channel', {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@ -522,7 +518,7 @@
|
|||||||
|
|
||||||
function fetchSearchTypes() {
|
function fetchSearchTypes() {
|
||||||
fetch('/api/v1/music/common?type=searchType', {
|
fetch('/api/v1/music/common?type=searchType', {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@ -569,11 +565,17 @@
|
|||||||
updateDownloadButton();
|
updateDownloadButton();
|
||||||
|
|
||||||
const resultDiv = document.getElementById('result');
|
const resultDiv = document.getElementById('result');
|
||||||
resultDiv.innerHTML = '';
|
resultDiv.innerHTML = `
|
||||||
document.getElementById('progress-container').style.display = 'none';
|
<div class="progress-container" id="progress-container" style="display:none;">
|
||||||
|
<p>下载进度:<span id="progress-text">0%</span></p>
|
||||||
|
<progress id="progress-bar" value="0" max="100"></progress>
|
||||||
|
</div>
|
||||||
|
`; // 重置时也恢复进度条位置
|
||||||
document.getElementById('progress-bar').value = 0;
|
document.getElementById('progress-bar').value = 0;
|
||||||
document.getElementById('progress-text').textContent = '0%';
|
document.getElementById('progress-text').textContent = '0%';
|
||||||
|
|
||||||
|
document.getElementById('loading').style.display = 'none';
|
||||||
|
|
||||||
fetchSearchData();
|
fetchSearchData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,7 +585,7 @@
|
|||||||
|
|
||||||
const keywords = document.getElementById('keywords').value.trim();
|
const keywords = document.getElementById('keywords').value.trim();
|
||||||
fetch(`/api/v1/music/search?channel=${selectedPlatformCode}&keywords=${encodeURIComponent(keywords)}&type=${selectedSearchTypeCode}&offset=${offset}&limit=${limit}`, {
|
fetch(`/api/v1/music/search?channel=${selectedPlatformCode}&keywords=${encodeURIComponent(keywords)}&type=${selectedSearchTypeCode}&offset=${offset}&limit=${limit}`, {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@ -679,10 +681,21 @@
|
|||||||
|
|
||||||
function displayAlbums(result, resultDiv) {
|
function displayAlbums(result, resultDiv) {
|
||||||
const albums = result.albums || [];
|
const albums = result.albums || [];
|
||||||
resultDiv.innerHTML = '';
|
hasMore = result.hasMore || false;
|
||||||
const albumList = document.createElement('div');
|
|
||||||
|
let albumList = resultDiv.querySelector('.album-list');
|
||||||
|
if (offset === 0) {
|
||||||
|
// 保留progress-container,不清空整个result,而是清空其内部列表
|
||||||
|
albumList = document.createElement('div');
|
||||||
albumList.className = 'album-list';
|
albumList.className = 'album-list';
|
||||||
resultDiv.appendChild(albumList);
|
resultDiv.appendChild(albumList);
|
||||||
|
} else {
|
||||||
|
if (!albumList) {
|
||||||
|
albumList = document.createElement('div');
|
||||||
|
albumList.className = 'album-list';
|
||||||
|
resultDiv.appendChild(albumList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
albums.forEach(album => {
|
albums.forEach(album => {
|
||||||
const albumItem = document.createElement('div');
|
const albumItem = document.createElement('div');
|
||||||
@ -706,14 +719,28 @@
|
|||||||
|
|
||||||
albumList.appendChild(albumItem);
|
albumList.appendChild(albumItem);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (hasMore) {
|
||||||
|
offset += limit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayArtists(result, resultDiv) {
|
function displayArtists(result, resultDiv) {
|
||||||
const artists = result.artists || [];
|
const artists = result.artists || [];
|
||||||
resultDiv.innerHTML = '';
|
hasMore = result.hasMore || false;
|
||||||
const artistList = document.createElement('div');
|
|
||||||
|
let artistList = resultDiv.querySelector('.artist-list');
|
||||||
|
if (offset === 0) {
|
||||||
|
artistList = document.createElement('div');
|
||||||
artistList.className = 'artist-list';
|
artistList.className = 'artist-list';
|
||||||
resultDiv.appendChild(artistList);
|
resultDiv.appendChild(artistList);
|
||||||
|
} else {
|
||||||
|
if (!artistList) {
|
||||||
|
artistList = document.createElement('div');
|
||||||
|
artistList.className = 'artist-list';
|
||||||
|
resultDiv.appendChild(artistList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
artists.forEach(artist => {
|
artists.forEach(artist => {
|
||||||
const artistItem = document.createElement('div');
|
const artistItem = document.createElement('div');
|
||||||
@ -730,21 +757,28 @@
|
|||||||
|
|
||||||
artistList.appendChild(artistItem);
|
artistList.appendChild(artistItem);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (hasMore) {
|
||||||
|
offset += limit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayPlaylists(result, resultDiv) {
|
function displayPlaylists(result, resultDiv) {
|
||||||
const playlists = result.playlists || [];
|
const playlists = result.playlists || [];
|
||||||
hasMore = result.hasMore || false;
|
hasMore = result.hasMore || false;
|
||||||
|
|
||||||
|
let playlistList = resultDiv.querySelector('.playlist-list');
|
||||||
if (offset === 0) {
|
if (offset === 0) {
|
||||||
// 第一次加载清空
|
playlistList = document.createElement('div');
|
||||||
resultDiv.innerHTML = '';
|
playlistList.className = 'playlist-list';
|
||||||
const playlistList = document.createElement('div');
|
resultDiv.appendChild(playlistList);
|
||||||
|
} else {
|
||||||
|
if (!playlistList) {
|
||||||
|
playlistList = document.createElement('div');
|
||||||
playlistList.className = 'playlist-list';
|
playlistList.className = 'playlist-list';
|
||||||
resultDiv.appendChild(playlistList);
|
resultDiv.appendChild(playlistList);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const playlistList = resultDiv.querySelector('.playlist-list');
|
|
||||||
|
|
||||||
playlists.forEach(pl => {
|
playlists.forEach(pl => {
|
||||||
const playlistItem = document.createElement('div');
|
const playlistItem = document.createElement('div');
|
||||||
@ -768,14 +802,20 @@
|
|||||||
|
|
||||||
function fetchAlbumSongs(albumId) {
|
function fetchAlbumSongs(albumId) {
|
||||||
fetch(`/api/v1/music/search/album?channel=${selectedPlatformCode}&id=${albumId}`, {
|
fetch(`/api/v1/music/search/album?channel=${selectedPlatformCode}&id=${albumId}`, {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
const songsData = data.data?.songs || [];
|
const songsData = data.data?.songs || [];
|
||||||
const resultDiv = document.getElementById('result');
|
const resultDiv = document.getElementById('result');
|
||||||
resultDiv.innerHTML = '';
|
// 清空除progress外的内容
|
||||||
|
resultDiv.innerHTML = `
|
||||||
|
<div class="progress-container" id="progress-container" style="display:none;">
|
||||||
|
<p>下载进度:<span id="progress-text">0%</span></p>
|
||||||
|
<progress id="progress-bar" value="0" max="100"></progress>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
allSongs = [];
|
allSongs = [];
|
||||||
selectedSongs = [];
|
selectedSongs = [];
|
||||||
const result = {
|
const result = {
|
||||||
@ -794,14 +834,19 @@
|
|||||||
|
|
||||||
function fetchArtistSongs(artistId) {
|
function fetchArtistSongs(artistId) {
|
||||||
fetch(`/api/v1/music/search/artist?channel=${selectedPlatformCode}&id=${artistId}`, {
|
fetch(`/api/v1/music/search/artist?channel=${selectedPlatformCode}&id=${artistId}`, {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
const hotSongs = data.data?.hotSongs || [];
|
const hotSongs = data.data?.hotSongs || [];
|
||||||
const resultDiv = document.getElementById('result');
|
const resultDiv = document.getElementById('result');
|
||||||
resultDiv.innerHTML = '';
|
resultDiv.innerHTML = `
|
||||||
|
<div class="progress-container" id="progress-container" style="display:none;">
|
||||||
|
<p>下载进度:<span id="progress-text">0%</span></p>
|
||||||
|
<progress id="progress-bar" value="0" max="100"></progress>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
allSongs = [];
|
allSongs = [];
|
||||||
selectedSongs = [];
|
selectedSongs = [];
|
||||||
const result = {
|
const result = {
|
||||||
@ -819,16 +864,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fetchPlaylistSongs(playlistId) {
|
function fetchPlaylistSongs(playlistId) {
|
||||||
// 获取歌单歌曲数据,返回 data.songs
|
|
||||||
fetch(`/api/v1/music/search/playlist?channel=${selectedPlatformCode}&id=${playlistId}`, {
|
fetch(`/api/v1/music/search/playlist?channel=${selectedPlatformCode}&id=${playlistId}`, {
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
const songsData = data.data?.songs || [];
|
const songsData = data.data?.songs || [];
|
||||||
const resultDiv = document.getElementById('result');
|
const resultDiv = document.getElementById('result');
|
||||||
resultDiv.innerHTML = '';
|
resultDiv.innerHTML = `
|
||||||
|
<div class="progress-container" id="progress-container" style="display:none;">
|
||||||
|
<p>下载进度:<span id="progress-text">0%</span></p>
|
||||||
|
<progress id="progress-bar" value="0" max="100"></progress>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
allSongs = [];
|
allSongs = [];
|
||||||
selectedSongs = [];
|
selectedSongs = [];
|
||||||
const result = {
|
const result = {
|
||||||
@ -850,15 +899,10 @@
|
|||||||
const windowHeight = window.innerHeight;
|
const windowHeight = window.innerHeight;
|
||||||
const bodyHeight = document.body.scrollHeight;
|
const bodyHeight = document.body.scrollHeight;
|
||||||
|
|
||||||
// 当搜索类型是单曲(1)或者歌单(1000)且有更多数据时,下拉加载更多
|
|
||||||
// 这里假设歌单也可以分页获取更多数据,在返回的result.hasMore中判断
|
|
||||||
// 若需要对不同类型单独判断分页逻辑,可根据实际需求调整
|
|
||||||
if (scrollTop + windowHeight >= bodyHeight - 100 && hasMore && !loading) {
|
if (scrollTop + windowHeight >= bodyHeight - 100 && hasMore && !loading) {
|
||||||
if (selectedSearchTypeCode == "1" || selectedSearchTypeCode == "1000") {
|
|
||||||
fetchSearchData();
|
fetchSearchData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSelectAll(e) {
|
function toggleSelectAll(e) {
|
||||||
const checked = e.target.checked;
|
const checked = e.target.checked;
|
||||||
@ -907,22 +951,20 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = selectedPlatformCode; // 渠道编号
|
const channel = selectedPlatformCode;
|
||||||
const progressContainer = document.getElementById('progress-container');
|
const progressContainer = document.getElementById('progress-container');
|
||||||
const progressBar = document.getElementById('progress-bar');
|
const progressBar = document.getElementById('progress-bar');
|
||||||
const progressText = document.getElementById('progress-text');
|
const progressText = document.getElementById('progress-text');
|
||||||
|
|
||||||
// 初始化进度条
|
|
||||||
progressContainer.style.display = 'block';
|
progressContainer.style.display = 'block';
|
||||||
progressBar.value = 0;
|
progressBar.value = 0;
|
||||||
progressText.textContent = '0%';
|
progressText.textContent = '0%';
|
||||||
|
|
||||||
const fetchBatchAndDownloadFile = async () => {
|
const fetchBatchAndDownloadFile = async () => {
|
||||||
try {
|
try {
|
||||||
// 1. 调用第一个接口,获取 batchNo
|
|
||||||
const batchRequestBody = {
|
const batchRequestBody = {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
idList: selectedSongs, // 假设selectedSongs是歌曲ID列表
|
idList: selectedSongs
|
||||||
};
|
};
|
||||||
const batchResponse = await fetch('/api/v1/music/download', {
|
const batchResponse = await fetch('/api/v1/music/download', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -932,24 +974,15 @@
|
|||||||
body: JSON.stringify(batchRequestBody),
|
body: JSON.stringify(batchRequestBody),
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
});
|
});
|
||||||
// const idListParam = selectedSongs.join(','); // 拼接ID集合
|
|
||||||
// const batchUrl = `/api/v1/music/download?channel=${channel}&idList=${encodeURIComponent(idListParam)}`;
|
|
||||||
//
|
|
||||||
// const batchResponse = await fetch(batchUrl, {
|
|
||||||
// method: 'GET',
|
|
||||||
// credentials: 'include',
|
|
||||||
// });
|
|
||||||
|
|
||||||
const batchData = await batchResponse.json();
|
const batchData = await batchResponse.json();
|
||||||
|
|
||||||
if (batchData.code === 200) {
|
if (batchData.code === 200) {
|
||||||
const batchNo = batchData.data; // 成功获取 batchNo
|
const batchNo = batchData.data;
|
||||||
|
|
||||||
// 更新进度条
|
|
||||||
progressBar.value = 50;
|
progressBar.value = 50;
|
||||||
progressText.textContent = '50%';
|
progressText.textContent = '50%';
|
||||||
|
|
||||||
// 2. 使用 batchNo 请求下载文件流
|
|
||||||
const fileUrl = `/api/v1/music/download/file?batchNo=${batchNo}&channel=${channel}`;
|
const fileUrl = `/api/v1/music/download/file?batchNo=${batchNo}&channel=${channel}`;
|
||||||
const fileResponse = await fetch(fileUrl, {
|
const fileResponse = await fetch(fileUrl, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
@ -957,16 +990,14 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (fileResponse.ok) {
|
if (fileResponse.ok) {
|
||||||
// 处理文件流并触发下载
|
|
||||||
const blob = await fileResponse.blob();
|
const blob = await fileResponse.blob();
|
||||||
const objectUrl = window.URL.createObjectURL(blob);
|
const objectUrl = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = objectUrl;
|
a.href = objectUrl;
|
||||||
a.download = 'music_files.zip'; // 下载文件名
|
a.download = 'music_files.zip';
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
|
|
||||||
// 清理资源
|
|
||||||
window.URL.revokeObjectURL(objectUrl);
|
window.URL.revokeObjectURL(objectUrl);
|
||||||
a.remove();
|
a.remove();
|
||||||
|
|
||||||
@ -981,18 +1012,14 @@
|
|||||||
console.error("下载过程中发生错误:", error);
|
console.error("下载过程中发生错误:", error);
|
||||||
alert("请求失败,请检查网络连接!");
|
alert("请求失败,请检查网络连接!");
|
||||||
} finally {
|
} finally {
|
||||||
// 更新进度条为 100%
|
|
||||||
progressBar.value = 100;
|
progressBar.value = 100;
|
||||||
progressText.textContent = '100%';
|
progressText.textContent = '100%';
|
||||||
// alert("下载完成!");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调用主函数
|
|
||||||
fetchBatchAndDownloadFile();
|
fetchBatchAndDownloadFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示用户名
|
|
||||||
function displayUsername() {
|
function displayUsername() {
|
||||||
const username = getCookie('username');
|
const username = getCookie('username');
|
||||||
const userInfoDiv = document.getElementById('user-info');
|
const userInfoDiv = document.getElementById('user-info');
|
||||||
@ -1003,45 +1030,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取Cookie的值
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
const value = `; ${document.cookie}`;
|
const value = `; ${document.cookie}`;
|
||||||
const parts = value.split(`; ${name}=`);
|
const parts = value.split(`; ${name}=`);
|
||||||
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
|
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置Cookie的值(可选)
|
|
||||||
function setCookie(name, value, days) {
|
|
||||||
const d = new Date();
|
|
||||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
||||||
let expires = "expires=" + d.toUTCString();
|
|
||||||
document.cookie = name + "=" + encodeURIComponent(value) + "; " + expires + "; path=/";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示消息并处理重定向
|
|
||||||
function showMessage(msg) {
|
function showMessage(msg) {
|
||||||
alert(msg);
|
alert(msg);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/login.html'; // 确保登录页面的路径正确
|
window.location.href = '/login.html';
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退出登录函数
|
|
||||||
function logout() {
|
function logout() {
|
||||||
fetch('/api/v1/user/logout', { // 假设后端的退出登录接口是 /api/v1/user/logout
|
fetch('/api/v1/user/logout', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'include' // 确保请求携带cookie
|
credentials: 'include'
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
// 清除可访问的cookie,如username
|
|
||||||
deleteCookie('username');
|
deleteCookie('username');
|
||||||
// 由于token是HttpOnly,无法通过JavaScript清除,后端已通过响应头清除
|
|
||||||
// 跳转回登录页面
|
|
||||||
window.location.href = '/login.html';
|
window.location.href = '/login.html';
|
||||||
} else {
|
} else {
|
||||||
// 显示错误信息
|
|
||||||
showMessage(data.msg || '退出登录失败,请稍后重试');
|
showMessage(data.msg || '退出登录失败,请稍后重试');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1051,12 +1063,10 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除Cookie的函数
|
|
||||||
function deleteCookie(name) {
|
function deleteCookie(name) {
|
||||||
document.cookie = name + '=; Max-Age=0; path=/';
|
document.cookie = name + '=; Max-Age=0; path=/';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 辅助函数:转义HTML,以防止XSS攻击
|
|
||||||
function escapeHTML(str) {
|
function escapeHTML(str) {
|
||||||
if (!str) return '';
|
if (!str) return '';
|
||||||
return str.replace(/[&<>"'`=\/]/g, function (s) {
|
return str.replace(/[&<>"'`=\/]/g, function (s) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user