Files
PC-official/static/js/index.js
DESKTOP-RQ919RC\Pc f8a3096a72 no message
2025-09-11 17:53:19 +08:00

500 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { createApp, ref, onMounted, nextTick, onUnmounted, computed } = Vue;
const search = createApp({
setup() {
const trait = [
{
icon: "./static/img/headset-icon.png",
title: "音乐创作",
text: "朴见潮音2024 年成立于广州,是专注 AI 音乐领域的创新工作室。短短一年便跻身于AI音乐浪潮先锋品牌",
},
{
icon: "./static/img/mv-icon.png",
title: "MV创作",
text: "以 AI 技术为核心整合音乐创作、MV 制作、教学培训、发行级重制等业务,为创作者和爱好者打造一站式平台。",
},
{
icon: "./static/img/train-icon.png",
title: "教学培训",
text: "工作室运用多种 AI 工具,突破传统创作局限,支持流行、摇滚等多元风格创作,满足个性化需求。",
},
{
icon: "./static/img/remake-icon.png",
title: "发行级重制",
text: "构建全流程服务体系,从 AI 音乐创作、MV 视觉呈现,到零基础教学,再到发行级重制提升品质,实现作品价值最大化。",
},
];
const text = `中国AIGC产业联盟AIGCxChina
温州市社科联
温州市新闻媒体中心
第一届AI音乐春晚 正选节目`;
const audioPlayer = ref(null);
const progress = ref(20); // 播放进度百分比
// 响应式变量存储当前播放时间和总时长
const currentTimeFormatted = ref('00:00');
const durationFormatted = ref('00:00');
// 格式化时间函数:将秒数转换为 MM:SS 格式
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
};
// 更新进度的函数
const getProgress = () => {
if (!audioPlayer.value) return;
const currentTime = audioPlayer.value.currentTime || 0;
const duration = audioPlayer.value.duration || 0;
const progress = duration > 0 ? (currentTime / duration) * 100 : 0;
setProgress(progress, audioPlayer.value.src);
// 更新时间显示
currentTimeFormatted.value = formatTime(currentTime);
durationFormatted.value = formatTime(duration);
};
const setProgress = (val, src) => {
audioList.value.forEach((item) => {
if (item.url === src) item.progress = val;
});
customList.value.forEach((item) => {
if (item.src === src) item.progress = val;
});
};
const introduceRef = ref(null);
const worksRef = ref(null);
const customRef = ref(null);
const studentRef = ref(null);
let pointerIndex = ref(0);
const albumBoxRef = ref(null);
// 点击侧边栏
const changePointer = (index) => {
albumBoxRef.value.scrollTo({ top: 448 * index, behavior: "smooth" });
pointerIndex.value = index;
};
// 向上滚动到上一页
const scrollToPrevious = () => {
let index = pointerIndex.value - 1;
if (index < 0) return;
changePointer(index);
};
// 向下滚动到下一页
const scrollToNext = () => {
let index = pointerIndex.value + 1;
if (index > bannerList.value.length) return;
changePointer(index);
};
// 获取当前在可视窗口中的元素ref
const visibleRef = computed(() => {
const visibleElement = elements.value.find((el) => el.isVisible);
return visibleElement ? visibleElement.ref : null;
});
let bannerList = ref([]);
let awardMVList = ref([]);
const init = () => {
ajaxget("https://pujianchaoyin.com/index/api").then((res) => {
if (res.code != 200) return;
const data = res.data;
bannerList.value = data.banner;
awardMVList.value = data.awardMVList;
nextTick(() => {
bannerSwiper();
});
});
};
let bannerSwiperTimer = null;
const bannerSwiper = () => {
bannerSwiperTimer = setTimeout(() => {
let index = pointerIndex.value + 1;
if (index > bannerList.value.length - 1) index = 0;
changePointer(index);
bannerSwiper();
}, 3000);
};
const changeInterval = (type) => {
if (type) clearTimeout(bannerSwiperTimer);
else bannerSwiper();
};
onMounted(() => {
init();
// 添加进度更新事件监听器
if (audioPlayer.value) {
console.log("volume", audioPlayer.value.volume);
audioPlayer.value.addEventListener("timeupdate", getProgress);
audioPlayer.value.addEventListener("loadedmetadata", getProgress);
}
studentList.value.forEach((item, index) => {
item["order"] = index;
// item["random"] = generateRandomString();
});
});
// 组件卸载时清理事件监听器
onUnmounted(() => {
audioPlayer?.value?.removeEventListener("timeupdate", getProgress);
audioPlayer?.value?.removeEventListener("loadedmetadata", getProgress);
});
// 头部播放状态
let audioHeadState = ref(false);
// 头部播放 - 开启
const playHead = () => {
closeAll();
nextTick(() => {
audioPlayer.value.src = "./static/mp3/1.MP3";
audioPlayer.value.play().then(() => (audioHeadState.value = true));
});
};
// 头部播放 - 暂停
const pauseHead = () => {
audioPlayer.value.pause();
audioHeadState.value = false;
};
// 播放 组件状态
let previewState = ref(false);
let art = null;
// 开启播放 MV
const openPreview = (url, poster = "") => {
previewState.value = true;
nextTick(() => {
art = new Artplayer({
container: ".artplayer-app",
url,
autoplay: true,
poster,
fullscreen: true,
});
art.play();
});
};
// 关闭播放 MV
const closePreview = () => {
previewState.value = false;
art?.destroy();
art = null;
};
let audioList = ref([
{
url: "https://app.gter.net/image/miniApp/mp3/1.mp3",
},
{
url: "https://app.gter.net/image/miniApp/mp3/2.mp3",
},
{
url: "https://app.gter.net/image/miniApp/mp3/3.mp3",
},
{
url: "https://app.gter.net/image/miniApp/mp3/4.mp3",
},
]);
const playAudio = (index) => {
closeAll();
nextTick(() => {
let target = audioList.value[index];
const url = target.url;
if (audioPlayer.value?.src != url) audioPlayer.value.src = url;
audioPlayer.value.play().then(() => {
target["state"] = true;
});
});
};
const pauseAudio = (index) => {
let target = audioList.value[index];
target["state"] = false;
audioPlayer.value.pause();
};
// 快进 和 后退 10秒
const fastForward = (type = "fast", src, area) => {
if (!audioPlayer.value) return;
if (audioPlayer.value.src != src) {
manageAudio(src, area);
return;
}
let currentTime = audioPlayer.value.currentTime || 0;
const duration = audioPlayer.value.duration || 0;
let newTime = 0;
if (type == "fast") newTime = Math.min(currentTime + 10, duration);
else newTime = Math.max(currentTime - 10, 0);
audioPlayer.value.currentTime = newTime;
getProgress();
};
const manageAudio = (src, area) => {
const audio = audioPlayer.value;
closeAll();
nextTick(() => {
if (area == "head") {
if (audio?.src != src) audio.src = src;
audio.play().then(() => (audioHeadState.value = true));
}
if (area == "works") {
if (audio?.src != src) audio.src = src;
audio.play().then(() => {
audioList.value.forEach((item) => {
if (item.url == src) item["state"] = true;
});
});
}
console.log("area", area, src);
if (area == "custom") {
if (audio?.src != src) audio.src = src;
audio.play().then(() => {
customList.value.forEach((item) => {
if (item.src == src) item["state"] = true;
});
});
}
});
};
const closeAll = () => {
audioPlayer.value.pause();
audioHeadState.value = false;
audioList.value.forEach((item) => {
item["progress"] = 0;
item["state"] = false;
});
customList.value.forEach((item) => {
item["progress"] = 0;
item["state"] = false;
});
};
let customList = ref([
{
src: "https://app.gter.net/image/miniApp/mp3/1.mp3",
},
{
src: "https://app.gter.net/image/miniApp/mp3/2.mp3",
},
{
src: "https://app.gter.net/image/miniApp/mp3/3.mp3",
},
{
src: "https://app.gter.net/image/miniApp/mp3/4.mp3",
},
]);
let studentIndex = ref(0);
let studentList = ref([
{
src: "https://app.gter.net/image/miniApp/mp3/1.mp3",
img: "./static/img/student-img.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/2.mp3",
img: "./static/img/student-img-2.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/3.mp3",
img: "./static/img/student-img-3.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/4.mp3",
img: "./static/img/student-img-4.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/4.mp3",
img: "./static/img/student-img-5.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/4.mp3",
img: "./static/img/student-img-6.png",
},
{
src: "https://app.gter.net/image/miniApp/mp3/4.mp3",
img: "./static/img/student-img-7.png",
},
]);
const cutStudent = (order) => {
// 找到目标元素和第一个元素
const [target, first] = [studentList.value.find((item) => item.order == order), studentList.value.find((item) => item.order == 0)];
// 交换order值
if (target && first && target !== first) {
[target.order, first.order] = [first.order, target.order];
}
};
const generateRandomString = () => {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
const length = 6;
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * chars.length);
result += chars.charAt(randomIndex);
}
return result;
};
// 响应式数据:音量值、是否静音
const volume = ref(84);
const isMuted = ref(false);
// 切换静音状态的方法
const toggleMute = () => {
isMuted.value = !isMuted.value;
if (audioPlayer.value) {
audioPlayer.value.muted = isMuted.value;
}
};
// 计算并设置音量百分比
const setVolumePercentage = (percentage) => {
// 确保百分比在0-100之间
const volumePercent = Math.max(0, Math.min(100, percentage));
volume.value = Math.abs(~~volumePercent);
// 设置音频元素的音量范围是0-1
if (audioPlayer.value) audioPlayer.value.volume = volumePercent / 100;
};
// 处理音量进度条点击
const handleVolumeClick = (event) => {
// 获取进度条元素
const progressBar = event.currentTarget;
const rect = progressBar.getBoundingClientRect();
// 计算点击位置相对于进度条的比例
// 因为是垂直进度条所以用clientY
const clickPosition = rect.bottom - event.clientY;
const percentage = (clickPosition / rect.height) * 100;
setVolumePercentage(percentage);
};
// 处理音量进度条拖拽
let isDragging = false;
const startDrag = (event) => {
isDragging = true;
handleVolumeDrag(event);
// 添加事件监听器
document.addEventListener("mousemove", handleVolumeDrag);
document.addEventListener("mouseup", stopDrag);
};
const handleVolumeDrag = (event) => {
if (!isDragging) return;
// 获取音量进度条元素
const progressBar = document.querySelector(".sound-control .progress");
if (!progressBar) return;
const rect = progressBar.getBoundingClientRect();
// 计算拖拽位置相对于进度条的比例
let dragPosition = rect.bottom - event.clientY;
// 限制在进度条范围内
dragPosition = Math.max(0, Math.min(dragPosition, rect.height));
const percentage = (dragPosition / rect.height) * 100;
setVolumePercentage(percentage);
};
const stopDrag = () => {
isDragging = false;
document.removeEventListener("mousemove", handleVolumeDrag);
document.removeEventListener("mouseup", stopDrag);
};
onMounted(() => {
// 绑定音量控制相关事件
const progressBar = document.querySelector(".sound-control .progress");
if (progressBar) {
progressBar.addEventListener("click", handleVolumeClick);
// 找到进度条内的滑块元素bar并绑定拖拽事件
const volumeBar = progressBar.querySelector(".bar");
if (volumeBar) volumeBar.addEventListener("mousedown", startDrag);
}
});
onUnmounted(() => {
// 清理音量控制相关事件
const progressBar = document.querySelector(".sound-control .progress");
if (progressBar) {
progressBar.removeEventListener("click", handleVolumeClick);
const volumeBar = progressBar.querySelector(".bar");
if (volumeBar) volumeBar.removeEventListener("mousedown", startDrag);
}
// 确保移除所有拖拽相关事件
document.removeEventListener("mousemove", handleVolumeDrag);
document.removeEventListener("mouseup", stopDrag);
});
const ajaxget = (url, data) => {
if (!data) data = {};
if (["localhost", "127.0.0.1"].includes(location.hostname)) data["authorization"] = "3338bf6a2e53dda872da3664a2560b25";
url = url.indexOf("https://") == -1 ? projectBaseURL2 + url : url;
// url += objectToQueryString(data);
return new Promise((resolve, reject) => {
axios
.get(url, {
emulateJSON: true,
withCredentials: true,
})
.then((res) => {
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
if (data.code == 401) {
openShowWindow();
reject();
}
if (data.code == 201) creationAlertBox("error", data.message || data.msg);
resolve(data);
})
.catch((error) => {
// console.log("resolve", resolve)
if (error.response?.status == 401) openShowWindow();
resolve("");
});
});
};
return { changeInterval, awardMVList, bannerList, albumBoxRef, volume, handleVolumeClick, handleVolumeDrag, startDrag, stopDrag, toggleMute, isMuted, volume, cutStudent, studentList, studentIndex, scrollToPrevious, scrollToNext, changePointer, pointerIndex, visibleRef, studentRef, customRef, formatTime, currentTimeFormatted, durationFormatted, worksRef, introduceRef, customList, closeAll, manageAudio, progress, pauseAudio, playAudio, audioList, closePreview, openPreview, previewState, audioHeadState, pauseHead, playHead, audioPlayer, text, trait, fastForward };
},
}).mount("#appIndex");