Skip to content

Commit 9b647cc

Browse files
committed
Merge remote-tracking branch 'origin/dev' into dev
2 parents 922b0c4 + 10f6a2b commit 9b647cc

File tree

13 files changed

+246
-117
lines changed

13 files changed

+246
-117
lines changed

src/api/ai/write/index.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { fetchEventSource } from '@microsoft/fetch-event-source'
2+
3+
import { getAccessToken } from '@/utils/auth'
4+
import { config } from '@/config/axios/config'
5+
import { AiWriteTypeEnum } from '@/views/ai/utils/constants'
6+
import request from '@/config/axios'
7+
8+
export interface WriteVO {
9+
type: AiWriteTypeEnum.WRITING | AiWriteTypeEnum.REPLY // 1:撰写 2:回复
10+
prompt: string // 写作内容提示 1。撰写 2回复
11+
originalContent: string // 原文
12+
length: number // 长度
13+
format: number // 格式
14+
tone: number // 语气
15+
language: number // 语言
16+
userId?: number // 用户编号
17+
platform?: string // 平台
18+
model?: string // 模型
19+
generatedContent?: string // 生成的内容
20+
errorMessage: string // 错误信息
21+
createTime?: Date // 创建时间
22+
}
23+
24+
export interface AiWritePageReqVO extends PageParam {
25+
userId?: number // 用户编号
26+
type?: AiWriteTypeEnum // 写作类型
27+
platform?: string // 平台
28+
createTime?: [string, string] // 创建时间
29+
}
30+
31+
export interface AiWriteRespVo {
32+
id: number
33+
userId: number
34+
type: number
35+
platform: string
36+
model: string
37+
prompt: string
38+
generatedContent: string
39+
originalContent: string
40+
length: number
41+
format: number
42+
tone: number
43+
language: number
44+
errorMessage: string
45+
createTime: string
46+
}
47+
48+
export const WriteApi = {
49+
writeStream: ({
50+
data,
51+
onClose,
52+
onMessage,
53+
onError,
54+
ctrl
55+
}: {
56+
data: WriteVO
57+
onMessage?: (res: any) => void
58+
onError?: (...args: any[]) => void
59+
onClose?: (...args: any[]) => void
60+
ctrl: AbortController
61+
}) => {
62+
const token = getAccessToken()
63+
return fetchEventSource(`${config.base_url}/ai/write/generate-stream`, {
64+
method: 'post',
65+
headers: {
66+
'Content-Type': 'application/json',
67+
Authorization: `Bearer ${token}`
68+
},
69+
openWhenHidden: true,
70+
body: JSON.stringify(data),
71+
onmessage: onMessage,
72+
onerror: onError,
73+
onclose: onClose,
74+
signal: ctrl.signal
75+
})
76+
},
77+
// 获取写作列表
78+
getWritePage: (params: AiWritePageReqVO) => {
79+
return request.get<PageResult<AiWriteRespVo[]>>({ url: `/ai/write/page`, params })
80+
},
81+
// 删除写作
82+
deleteWrite(id: number) {
83+
return request.delete({ url: `/ai/write/delete`, params: { id } })
84+
}
85+
}

src/api/ai/writer/index.ts

Lines changed: 0 additions & 65 deletions
This file was deleted.

src/views/ai/music/components/index.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex h-1/1">
2+
<div class="flex ">
33
<!-- 模式 -->
44
<Mode class="flex-none" @generate-music="generateMusic"/>
55
<!-- 音频列表 -->
@@ -13,7 +13,7 @@ import List from './list/index.vue'
1313
1414
defineOptions({ name: 'Index' })
1515
16-
const listRef = ref<{generateMusic: (...args) => void} | null>(null)
16+
const listRef = ref<Nullable<{generateMusic: (...args) => void}>>(null)
1717
1818
function generateMusic (args: {formData: Recordable}) {
1919
unref(listRef)?.generateMusic(args.formData)
Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,68 @@
11
<template>
2-
<div class="h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">播放器</div>
2+
<div class="flex items-center justify-between px-2 h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">
3+
<!-- 歌曲信息 -->
4+
<div class="flex gap-[10px]">
5+
<el-image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" class="w-[45px]"/>
6+
<div>
7+
<div>我很好</div>
8+
<div class="text-[12px] text-gray-400">刘大壮</div>
9+
</div>
10+
</div>
11+
12+
<!-- 音频controls -->
13+
<div class="flex gap-[12px] items-center">
14+
<Icon icon="majesticons:back-circle" :size="20" class="text-gray-300 cursor-pointer"/>
15+
<Icon :icon="audioProps.paused ? 'mdi:arrow-right-drop-circle' : 'solar:pause-circle-bold'" :size="30" class=" cursor-pointer" @click="toggleStatus('paused')"/>
16+
<Icon icon="majesticons:next-circle" :size="20" class="text-gray-300 cursor-pointer"/>
17+
<div class="flex gap-[16px] items-center">
18+
<span>{{audioProps.currentTime}}</span>
19+
<el-slider v-model="audioProps.duration" color="#409eff" class="w-[160px!important] "/>
20+
<span>{{ audioProps.duration }}</span>
21+
</div>
22+
<!-- 音频 -->
23+
<audio v-bind="audioProps" ref="audioRef" controls v-show="!audioProps" @timeupdate="audioTimeUpdate">
24+
<source :src="response"/>
25+
</audio>
26+
</div>
27+
28+
<!-- 音量控制器 -->
29+
<div class="flex gap-[16px] items-center">
30+
<Icon :icon="audioProps.muted ? 'tabler:volume-off' : 'tabler:volume'" :size="20" class="cursor-pointer" @click="toggleStatus('muted')"/>
31+
<el-slider v-model="audioProps.volume" color="#409eff" class="w-[160px!important] "/>
32+
</div>
33+
</div>
334
</template>
435

536
<script lang="ts" setup>
37+
import { formatPast } from '@/utils/formatTime'
38+
import response from '@/assets/audio/response.mp3'
639
740
defineOptions({ name: 'Index' })
841
42+
const audioRef = ref<Nullable<HTMLElement>>(null)
43+
// 音频相关属性https://www.runoob.com/tags/ref-av-dom.html
44+
const audioProps = reactive({
45+
autoplay: true,
46+
paused: false,
47+
currentTime: '00:00',
48+
duration: '00:00',
49+
muted: false,
50+
volume: 50,
51+
})
52+
53+
function toggleStatus (type: string) {
54+
audioProps[type] = !audioProps[type]
55+
if (type === 'paused' && audioRef.value) {
56+
if (audioProps[type]) {
57+
audioRef.value.pause()
58+
} else {
59+
audioRef.value.play()
60+
}
61+
}
62+
}
63+
64+
// 更新播放位置
65+
function audioTimeUpdate (args) {
66+
audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss')
67+
}
968
</script>

src/views/ai/music/components/list/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex flex-col h-full">
2+
<div class="flex flex-col h-[600px]">
33
<div class="flex-auto flex overflow-hidden">
44
<el-tabs v-model="currentType" class="flex-auto px-[var(--app-content-padding)]">
55
<!-- 我的创作 -->

src/views/ai/music/components/mode/index.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<ContentWrap class="w-300px h-full">
2+
<ContentWrap class="w-300px h-full mb-[0!important]">
33
<el-radio-group v-model="generateMode" class="mb-15px">
44
<el-radio-button label="desc">
55
描述模式
@@ -28,10 +28,7 @@ const emits = defineEmits(['generate-music'])
2828
2929
const generateMode = ref('lyric')
3030
31-
interface ModeRef {
32-
formData: Recordable
33-
}
34-
const modeRef = ref<ModeRef | null>(null)
31+
const modeRef = ref<Nullable<{ formData: Recordable }>>(null)
3532
3633
/*
3734
*@Description: 根据信息生成音乐

src/views/ai/utils/constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ export enum AiWriteTypeEnum {
6464
REPLY // 回复
6565
}
6666

67+
// 表格展示对照map
68+
export const AiWriteTypeTableRender = {
69+
[AiWriteTypeEnum.WRITING]: '撰写',
70+
[AiWriteTypeEnum.REPLY]: '回复',
71+
}
72+
6773
// ========== 【图片 UI】相关的枚举 ==========
6874
export const ImageHotWords = [
6975
'中国旗袍',

src/views/ai/writer/index/components/Left.vue renamed to src/views/ai/write/index/components/Left.vue

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,28 @@
2424
</h3>
2525
</DefineLabel>
2626

27-
<div class="relative" v-bind="$attrs">
27+
<div class="flex flex-col" v-bind="$attrs">
2828
<!-- tab -->
29-
<div
30-
class="absolute left-1/2 top-2 -translate-x-1/2 w-[303px] rounded-full bg-[#DDDFE3] p-1 z-10"
31-
>
32-
<div
33-
class="flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
34-
:class="selectedTab === AiWriteTypeEnum.REPLY && 'after:transform after:translate-x-[100%]'"
35-
>
36-
<ReuseTab
37-
v-for="tab in tabs"
38-
:key="tab.value"
39-
:text="tab.text"
40-
:active="tab.value === selectedTab"
41-
:itemClick="() => switchTab(tab.value)"
42-
/>
29+
<div class="w-full pt-2 bg-[#f5f7f9] flex justify-center">
30+
<div class="w-[303px] rounded-full bg-[#DDDFE3] p-1 z-10">
31+
<div
32+
class="flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
33+
:class="
34+
selectedTab === AiWriteTypeEnum.REPLY && 'after:transform after:translate-x-[100%]'
35+
"
36+
>
37+
<ReuseTab
38+
v-for="tab in tabs"
39+
:key="tab.value"
40+
:text="tab.text"
41+
:active="tab.value === selectedTab"
42+
:itemClick="() => switchTab(tab.value)"
43+
/>
44+
</div>
4345
</div>
4446
</div>
4547
<div
46-
class="px-7 pb-2 pt-[46px] overflow-y-auto lg:block w-[380px] box-border bg-[#ECEDEF] h-full"
48+
class="px-7 pb-2 flex-grow overflow-y-auto lg:block w-[380px] box-border bg-[#f5f7f9] h-full"
4749
>
4850
<div>
4951
<template v-if="selectedTab === 1">
@@ -102,7 +104,7 @@
102104
import { createReusableTemplate } from '@vueuse/core'
103105
import { ref } from 'vue'
104106
import Tag from './Tag.vue'
105-
import { WriteVO } from '@/api/ai/writer'
107+
import { WriteVO } from 'src/api/ai/write'
106108
import { omit } from 'lodash-es'
107109
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
108110
import { AiWriteTypeEnum, WriteExample } from '@/views/ai/utils/constants'
@@ -177,10 +179,18 @@ const initData: WriteVO = {
177179
}
178180
const formData = ref<WriteVO>({ ...initData })
179181
182+
/** 用来记录切换之前所填写的数据,切换的时候给赋值回来 **/
183+
const recordFormData = {} as Record<AiWriteTypeEnum, WriteVO>
184+
180185
/** 切换tab **/
181186
const switchTab = (value: TabType) => {
182-
selectedTab.value = value
183-
formData.value = { ...initData }
187+
if (value !== selectedTab.value) {
188+
// 保存之前的久数据
189+
recordFormData[selectedTab.value] = formData.value
190+
selectedTab.value = value
191+
// 将之前的旧数据赋值回来
192+
formData.value = { ...initData, ...recordFormData[value] }
193+
}
184194
}
185195
186196
/** 提交写作 */

0 commit comments

Comments
 (0)