|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<view class="make-music-detail">
|
|
|
<!-- 顶部导航 -->
|
|
|
- <view class="nav-bar">
|
|
|
+ <!-- <view class="nav-bar">
|
|
|
<view class="left">
|
|
|
<view class="uni-btn-icon" @click="goBack"></view>
|
|
|
</view>
|
|
@@ -9,40 +9,84 @@
|
|
|
<view class="right">
|
|
|
<view class="coinM">
|
|
|
<image src="/static/icon/coin_m.png" mode="aspectFit"></image>
|
|
|
- <text>{{myinfo.num_gmm}}</text>
|
|
|
+ <text>{{ myinfo.num_gmm }}</text>
|
|
|
</view>
|
|
|
<view class="coinC">
|
|
|
<image src="/static/icon/coin_cd.png" mode="aspectFit"></image>
|
|
|
- <text>{{myinfo.num_gmd}}</text>
|
|
|
+ <text>{{ myinfo.num_gmd }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
+ </view> -->
|
|
|
|
|
|
- <!-- 队列状态显示 -->
|
|
|
+ <!-- 顶部导航 -->
|
|
|
+ <view class="nav-bar">
|
|
|
+ <view class="left">
|
|
|
+ <view class="uni-btn-icon" @click="goBack"></view>
|
|
|
+ <view class="create">音乐制作</view>
|
|
|
+ <image src="@/static/makedetail/cz_icon_lingganchuangzuo.png" class="edit"></image>
|
|
|
+ </view>
|
|
|
+ <view class="right">
|
|
|
+ <view class="coinM">
|
|
|
+ <image src="/static/icon/coin_m.png" mode="aspectFit"></image>
|
|
|
+ <text>{{ myinfo.num_gmm }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="coinC">
|
|
|
+ <image src="/static/icon/coin_cd.png" mode="aspectFit"></image>
|
|
|
+ <text>{{ myinfo.num_gmd }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 队列状态显示
|
|
|
<view class="preview-section" v-if="inQueue">
|
|
|
<view class="preview-card">
|
|
|
<image class="loading-icon" src="/static/loading.png" mode="aspectFit"></image>
|
|
|
<text class="loading-text">{{queueMessage}}</text>
|
|
|
<text class="sub-text">请耐心等待制作完成</text>
|
|
|
</view>
|
|
|
+ </view> -->
|
|
|
+
|
|
|
+ <!-- 排队预览区域 -->
|
|
|
+ <view class="preview-section lineUp-section" v-if="queuing">
|
|
|
+ <view class="section-title">
|
|
|
+ <text>创作预览</text>
|
|
|
+ <view class="member-box">
|
|
|
+ <image src="@/static/makedetail/wd_icon_vip(1).png" mode="aspectFit"></image>
|
|
|
+ 升级会员插队加速
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="preview-card">
|
|
|
+ <image src="@/static/makedetail/cz_icon_jiazai.png" mode="aspectFit"></image>
|
|
|
+ <view class="text1">{{ queueMessage }}</view>
|
|
|
+ <view class="text2">退出不影响继续生成</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 创作预览区域 -->
|
|
|
+ <view class="preview-section" v-if="inQueue">
|
|
|
+ <view class="section-title">创作预览</view>
|
|
|
+ <view class="preview-card">
|
|
|
+ <image src="@/static/makedetail/cz_icon_shengcheng.png" mode="aspectFit"></image>
|
|
|
+ <view class="text1">生成中0%</view>
|
|
|
+ <view class="text2">退出不影响继续生成</view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
+
|
|
|
<!-- 主要内容区 -->
|
|
|
- <view class="content" v-if="!inQueue">
|
|
|
+ <view class="content">
|
|
|
<!-- 歌曲名称输入 -->
|
|
|
<view class="input-section">
|
|
|
<text class="label">歌曲名称</text>
|
|
|
<input type="text" placeholder="请输入名称..." class="input-field" maxlength="30" v-model="songName" />
|
|
|
- <text class="count">{{songName.length}}/30</text>
|
|
|
+ <text class="count">{{ songName.length }}/30</text>
|
|
|
</view>
|
|
|
|
|
|
<!-- 创作歌词输入 -->
|
|
|
<view class="input-section">
|
|
|
<text class="label">创作歌词</text>
|
|
|
<textarea placeholder="请在此处输入您想要进行联想的内容或者歌词" class="textarea-field" maxlength="800" v-model="lyrics"
|
|
|
- :style="{height: textareaHeight + 'px'}" @input="onTextareaInput" />
|
|
|
+ :style="{ height: textareaHeight + 'px' }" @input="onTextareaInput" />
|
|
|
<view class="textarea-footer">
|
|
|
- <text class="count">{{lyrics.length}}/800</text>
|
|
|
+ <text class="count">{{ lyrics.length }}/800</text>
|
|
|
<text class="ai-btn" v-if="false">AI润词</text>
|
|
|
</view>
|
|
|
</view>
|
|
@@ -51,215 +95,237 @@
|
|
|
<view class="style-section">
|
|
|
<text class="label">音乐风格</text>
|
|
|
<view class="tabs">
|
|
|
- <text :class="{'active': selectedTab === 'emotion'}" @click="selectTab('emotion')">情感</text>
|
|
|
- <text :class="{'active': selectedTab === 'genre'}" @click="selectTab('genre')">流派</text>
|
|
|
- <text :class="{'active': selectedTab === 'era'}" @click="selectTab('era')">年代</text>
|
|
|
- <text :class="{'active': selectedTab === 'instrument'}" @click="selectTab('instrument')">乐器</text>
|
|
|
+ <text :class="{ 'active': selectedTab === 'emotion' }" @click="selectTab('emotion')">情感</text>
|
|
|
+ <text :class="{ 'active': selectedTab === 'genre' }" @click="selectTab('genre')">流派</text>
|
|
|
+ <text :class="{ 'active': selectedTab === 'era' }" @click="selectTab('era')">年代</text>
|
|
|
+ <text :class="{ 'active': selectedTab === 'instrument' }" @click="selectTab('instrument')">乐器</text>
|
|
|
</view>
|
|
|
<view class="tags">
|
|
|
<text v-for="(tag, index) in currentTags" :key="index"
|
|
|
:class="['tag', { active: selectedTags[selectedTab].includes(tag) }]" @click="toggleTag(tag)">
|
|
|
- {{tag}}
|
|
|
+ {{ tag }}
|
|
|
</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 底部按钮 -->
|
|
|
- <view class="bottom-section" v-if="!inQueue">
|
|
|
- <button class="submit-btn" @click="generateMusic">立即生成<text class="small">(需消耗10枚豆)</text></button>
|
|
|
- <view class="promotion-text">
|
|
|
- <text class="link-text">即刻开通订阅,我取各种福利</text>
|
|
|
+ // <view class="bottom-section" v-if="!inQueue">
|
|
|
+ // <button class="submit-btn" @click="generateMusic">立即生成<text class="small">(需消耗10枚豆)</text></button>
|
|
|
+ // <view class="promotion-text">
|
|
|
+ // <text class="link-text">即刻开通订阅,我取各种福利</text>
|
|
|
+ // </view>
|
|
|
+ // </view>
|
|
|
+
|
|
|
+ <!-- 底部按钮 -->
|
|
|
+ <view class="bottom-button">
|
|
|
+ <button v-if="!doYouWantToEdit" class="generate-btn" @click="generateMusic">立即生成
|
|
|
+ <image src="/static/icon/coin_cd.png" mode="aspectFit"></image>
|
|
|
+ 10
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <view v-else class="generate-btn prohibit">生成中
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+ <view class="promotion-link">
|
|
|
+ <image class="vip" src="/static/makedetail/wd_icon_vip(1).png" mode="aspectFit"></image>
|
|
|
+ <text> 即刻开通订阅,获取各种福利! </text>
|
|
|
+ <image class="jiantou" src="/static/makedetail/cz_icon_jiantou.png" mode="aspectFit"></image>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
- export default {
|
|
|
- name: 'MakeMusicDetail',
|
|
|
- data() {
|
|
|
- return {
|
|
|
- songName: '',
|
|
|
- lyrics: '',
|
|
|
- selectedTags: {
|
|
|
- emotion: [],
|
|
|
- genre: [],
|
|
|
- era: [],
|
|
|
- instrument: []
|
|
|
+export default {
|
|
|
+ name: 'MakeMusicDetail',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ songName: '',
|
|
|
+ lyrics: '',
|
|
|
+ selectedTags: {
|
|
|
+ emotion: [],
|
|
|
+ genre: [],
|
|
|
+ era: [],
|
|
|
+ instrument: []
|
|
|
+ },
|
|
|
+ textareaHeight: 120,
|
|
|
+ minHeight: 120,
|
|
|
+ selectedTab: 'emotion',
|
|
|
+ tagOptions: {
|
|
|
+ emotion: ['欢快', '悲伤', '积极', '浪漫', '忧郁', '华丽', '闪耀', '神秘', '惊怒', '紧张', '恐怖', '平静'],
|
|
|
+ genre: ['流行', '摇滚', '民谣', '电子', 'R&B', '嘻哈', '古典', '爵士'],
|
|
|
+ era: ['80年代', '90年代', '00年代', '10年代', '20年代'],
|
|
|
+ instrument: ['钢琴', '吉他', '贝斯', '鼓', '小提琴', '萨克斯', '电子合成器']
|
|
|
+ },
|
|
|
+ inQueue: true,//是否创作中
|
|
|
+ queuing: true,//是否排队中
|
|
|
+ queueMessage: '',
|
|
|
+ myinfo: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad() {
|
|
|
+ // this.checkQueueStatus();
|
|
|
+ this.getMyInfo();
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ currentTags() {
|
|
|
+ return this.selectedTab ? this.tagOptions[this.selectedTab] : [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ doYouWantToEdit() {
|
|
|
+ return this.inQueue || this.queuing
|
|
|
+ },
|
|
|
+ goBack() {
|
|
|
+ uni.navigateBack({
|
|
|
+ delta: 1
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getMyInfo() {
|
|
|
+ uni.request({
|
|
|
+ url: this.$apiHost + '/My/getnum',
|
|
|
+ method: 'GET',
|
|
|
+ header: {
|
|
|
+ 'content-type': 'application/json',
|
|
|
+ 'sign': getApp().globalData.headerSign
|
|
|
},
|
|
|
- textareaHeight: 120,
|
|
|
- minHeight: 120,
|
|
|
- selectedTab: 'emotion',
|
|
|
- tagOptions: {
|
|
|
- emotion: ['欢快', '悲伤', '积极', '浪漫', '忧郁', '华丽', '闪耀', '神秘', '惊怒', '紧张', '恐怖', '平静'],
|
|
|
- genre: ['流行', '摇滚', '民谣', '电子', 'R&B', '嘻哈', '古典', '爵士'],
|
|
|
- era: ['80年代', '90年代', '00年代', '10年代', '20年代'],
|
|
|
- instrument: ['钢琴', '吉他', '贝斯', '鼓', '小提琴', '萨克斯', '电子合成器']
|
|
|
+ data: {
|
|
|
+ uuid: getApp().globalData.uuid
|
|
|
},
|
|
|
- inQueue: false,
|
|
|
- queueMessage: '',
|
|
|
- myinfo: {}
|
|
|
- }
|
|
|
+ success: (res) => {
|
|
|
+ console.log("获取用户信息:", res.data);
|
|
|
+ this.myinfo = res.data
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
},
|
|
|
- onLoad() {
|
|
|
- // this.checkQueueStatus();
|
|
|
+ checkQueueStatus() {
|
|
|
+ uni.request({
|
|
|
+ url: this.$apiHost + '/WorkAI/queueStatus',
|
|
|
+ method: 'GET',
|
|
|
+ header: {
|
|
|
+ 'content-type': 'application/json',
|
|
|
+ 'sign': getApp().globalData.headerSign
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ uuid: getApp().globalData.uuid,
|
|
|
+ task_type: 2
|
|
|
+ },
|
|
|
+ success: (res) => {
|
|
|
+ console.log("音乐队列状态:", res.data);
|
|
|
+ if (res.data.success === "yes") {
|
|
|
+ this.inQueue = res.data.in_queue
|
|
|
+ if (this.inQueue) {
|
|
|
+ this.queueMessage = res.data.str
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.log('获取队列状态失败:', err);
|
|
|
+ uni.showToast({
|
|
|
+ title: '获取状态失败',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
this.getMyInfo();
|
|
|
},
|
|
|
- computed: {
|
|
|
- currentTags() {
|
|
|
- return this.selectedTab ? this.tagOptions[this.selectedTab] : [];
|
|
|
+ generateMusic() {
|
|
|
+ if (!this.songName.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入歌曲名称',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
}
|
|
|
- },
|
|
|
- methods: {
|
|
|
- goBack() {
|
|
|
- uni.navigateBack({
|
|
|
- delta: 1
|
|
|
- });
|
|
|
- },
|
|
|
- getMyInfo() {
|
|
|
- uni.request({
|
|
|
- url: this.$apiHost + '/My/getnum',
|
|
|
- method: 'GET',
|
|
|
- header: {
|
|
|
- 'content-type': 'application/json',
|
|
|
- 'sign': getApp().globalData.headerSign
|
|
|
- },
|
|
|
- data: {
|
|
|
- uuid: getApp().globalData.uuid
|
|
|
- },
|
|
|
- success: (res) => {
|
|
|
- console.log("获取用户信息:", res.data);
|
|
|
- this.myinfo = res.data
|
|
|
- }
|
|
|
+ if (!this.lyrics.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入歌词内容',
|
|
|
+ icon: 'none'
|
|
|
})
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- },
|
|
|
- checkQueueStatus() {
|
|
|
- uni.request({
|
|
|
- url: this.$apiHost + '/WorkAI/queueStatus',
|
|
|
- method: 'GET',
|
|
|
- header: {
|
|
|
- 'content-type': 'application/json',
|
|
|
- 'sign': getApp().globalData.headerSign
|
|
|
- },
|
|
|
- data: {
|
|
|
- uuid: getApp().globalData.uuid,
|
|
|
- task_type: 2
|
|
|
- },
|
|
|
- success: (res) => {
|
|
|
- console.log("音乐队列状态:", res.data);
|
|
|
- if (res.data.success === "yes") {
|
|
|
- this.inQueue = res.data.in_queue
|
|
|
- if (this.inQueue) {
|
|
|
- this.queueMessage = res.data.str
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.log('获取队列状态失败:', err);
|
|
|
- uni.showToast({
|
|
|
- title: '获取状态失败',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- }
|
|
|
- })
|
|
|
- this.getMyInfo();
|
|
|
- },
|
|
|
- generateMusic() {
|
|
|
- if (!this.songName.trim()) {
|
|
|
+ // 合并所有选中的标签
|
|
|
+ let allSelectedTags = [
|
|
|
+ ...this.selectedTags.emotion,
|
|
|
+ ...this.selectedTags.genre,
|
|
|
+ ...this.selectedTags.era,
|
|
|
+ ...this.selectedTags.instrument
|
|
|
+ ];
|
|
|
+
|
|
|
+ let that = this
|
|
|
+ uni.request({
|
|
|
+ url: this.$apiHost + '/WorkAI/creatorMusic',
|
|
|
+ data: {
|
|
|
+ uuid: getApp().globalData.uuid,
|
|
|
+ name: this.songName,
|
|
|
+ lyrics: this.lyrics,
|
|
|
+ style: allSelectedTags.join(',')
|
|
|
+ },
|
|
|
+ method: 'POST',
|
|
|
+ header: {
|
|
|
+ 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
+ 'sign': getApp().globalData.headerSign
|
|
|
+ },
|
|
|
+ dataType: 'json',
|
|
|
+ success: (res) => {
|
|
|
+ console.log("生成结果:", res.data);
|
|
|
uni.showToast({
|
|
|
- title: '请输入歌曲名称',
|
|
|
+ title: res.data.str || '请求成功',
|
|
|
icon: 'none'
|
|
|
- })
|
|
|
- return
|
|
|
- }
|
|
|
- if (!this.lyrics.trim()) {
|
|
|
+ });
|
|
|
+ if (res.data.success == "yes") {
|
|
|
+ setTimeout(function () {
|
|
|
+ // that.checkQueueStatus()
|
|
|
+ //返回上一页
|
|
|
+ uni.navigateBack()
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.log('生成失败:', err);
|
|
|
uni.showToast({
|
|
|
- title: '请输入歌词内容',
|
|
|
+ title: '生成请求失败',
|
|
|
icon: 'none'
|
|
|
- })
|
|
|
- return
|
|
|
+ });
|
|
|
}
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onTextareaInput(e) {
|
|
|
+ const lineHeight = 20; // 假设每行高度为20px
|
|
|
+ const padding = 30; // 上下padding各15px
|
|
|
+ const value = e.detail.value;
|
|
|
+ const lines = value.split('\n').length;
|
|
|
+ // 计算每行的平均字符数
|
|
|
+ const avgCharsPerLine = 30; // 根据实际输入框宽度调整
|
|
|
+ const textLines = Math.ceil(value.length / avgCharsPerLine);
|
|
|
|
|
|
- // 合并所有选中的标签
|
|
|
- let allSelectedTags = [
|
|
|
- ...this.selectedTags.emotion,
|
|
|
- ...this.selectedTags.genre,
|
|
|
- ...this.selectedTags.era,
|
|
|
- ...this.selectedTags.instrument
|
|
|
- ];
|
|
|
-
|
|
|
- let that = this
|
|
|
- uni.request({
|
|
|
- url: this.$apiHost + '/WorkAI/creatorMusic',
|
|
|
- data: {
|
|
|
- uuid: getApp().globalData.uuid,
|
|
|
- name: this.songName,
|
|
|
- lyrics: this.lyrics,
|
|
|
- style: allSelectedTags.join(',')
|
|
|
- },
|
|
|
- method: 'POST',
|
|
|
- header: {
|
|
|
- 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
- 'sign': getApp().globalData.headerSign
|
|
|
- },
|
|
|
- dataType: 'json',
|
|
|
- success: (res) => {
|
|
|
- console.log("生成结果:", res.data);
|
|
|
- uni.showToast({
|
|
|
- title: res.data.str || '请求成功',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- if (res.data.success == "yes") {
|
|
|
- setTimeout(function() {
|
|
|
- // that.checkQueueStatus()
|
|
|
- //返回上一页
|
|
|
- uni.navigateBack()
|
|
|
- }, 500);
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.log('生成失败:', err);
|
|
|
- uni.showToast({
|
|
|
- title: '生成请求失败',
|
|
|
- icon: 'none'
|
|
|
- });
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- onTextareaInput(e) {
|
|
|
- const lineHeight = 20; // 假设每行高度为20px
|
|
|
- const padding = 30; // 上下padding各15px
|
|
|
- const value = e.detail.value;
|
|
|
- const lines = value.split('\n').length;
|
|
|
- // 计算每行的平均字符数
|
|
|
- const avgCharsPerLine = 30; // 根据实际输入框宽度调整
|
|
|
- const textLines = Math.ceil(value.length / avgCharsPerLine);
|
|
|
-
|
|
|
- // 取行数的最大值,确保有足够空间显示
|
|
|
- const totalLines = Math.max(lines, textLines);
|
|
|
- const newHeight = Math.max(totalLines * lineHeight + padding, this.minHeight);
|
|
|
+ // 取行数的最大值,确保有足够空间显示
|
|
|
+ const totalLines = Math.max(lines, textLines);
|
|
|
+ const newHeight = Math.max(totalLines * lineHeight + padding, this.minHeight);
|
|
|
|
|
|
- this.textareaHeight = newHeight;
|
|
|
- },
|
|
|
- selectTab(tab) {
|
|
|
- if (this.selectedTab !== tab) {
|
|
|
- this.selectedTab = tab;
|
|
|
- // 不再清空已选择的标签
|
|
|
- }
|
|
|
- },
|
|
|
- toggleTag(tag) {
|
|
|
- if (this.selectedTags[this.selectedTab].includes(tag)) {
|
|
|
- this.selectedTags[this.selectedTab] = this.selectedTags[this.selectedTab].filter(t => t !== tag);
|
|
|
- } else {
|
|
|
- this.selectedTags[this.selectedTab].push(tag);
|
|
|
- }
|
|
|
+ this.textareaHeight = newHeight;
|
|
|
+ },
|
|
|
+ selectTab(tab) {
|
|
|
+ if (this.selectedTab !== tab) {
|
|
|
+ this.selectedTab = tab;
|
|
|
+ // 不再清空已选择的标签
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toggleTag(tag) {
|
|
|
+ if (this.selectedTags[this.selectedTab].includes(tag)) {
|
|
|
+ this.selectedTags[this.selectedTab] = this.selectedTags[this.selectedTab].filter(t => t !== tag);
|
|
|
+ } else {
|
|
|
+ this.selectedTags[this.selectedTab].push(tag);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
- @import './makeMusicDetail.scss';
|
|
|
+@import './makeMusicDetail.scss';
|
|
|
</style>
|