Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ai_web_page_prod
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
haojie
ai_web_page_prod
Commits
581b5739
Commit
581b5739
authored
May 19, 2023
by
haojie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
15592f93
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1462 additions
and
175 deletions
+1462
-175
src/components/Admin/AdminPublicPage.vue
+47
-1
src/components/Admin/CompleteAudio.vue
+455
-0
src/components/Admin/GenerateVoice.vue
+47
-12
src/components/Admin/PageEdit.vue
+74
-13
src/components/Admin/RowPopup.vue
+1
-1
src/components/Admin/Textarea.vue
+4
-3
src/components/Admin/audio.vue
+8
-1
src/components/Admin/table.vue
+40
-19
src/constants/admin_form.ts
+103
-5
src/hooks/ConvertVoice.ts
+122
-0
src/pages/AILiveStreaming/DiscourseManagement/index.vue
+11
-11
src/pages/AILiveStreaming/DiscourseManagementCreate/index.vue
+101
-11
src/pages/AILiveStreaming/DiscourseManagementEdit/index.vue
+135
-14
src/pages/AILiveStreaming/InteractiveSetting/index.vue
+81
-39
src/pages/AILiveStreaming/InteractiveSettingCreate/index.vue
+64
-18
src/pages/AILiveStreaming/InteractiveSettingEdit/index.vue
+48
-23
src/utils/api/ai.ts
+112
-3
src/utils/request.ts
+1
-1
src/utils/tool.ts
+8
-0
No files found.
src/components/Admin/AdminPublicPage.vue
View file @
581b5739
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
<RowPopup
<RowPopup
:list=
"form.row_selected_options"
:list=
"form.row_selected_options"
:len=
"SelectedRows.length"
:len=
"SelectedRows.length"
@
change=
"MultiSelectEvent"
></RowPopup>
></RowPopup>
</
template
>
</
template
>
<
template
v-if=
"form.refresh"
>
<
template
v-if=
"form.refresh"
>
...
@@ -69,13 +70,13 @@
...
@@ -69,13 +70,13 @@
</template>
</template>
<div
class=
"admin-table"
>
<div
class=
"admin-table"
>
<CustomTable
<CustomTable
:list=
"list"
:columns=
"form.table_columns"
:columns=
"form.table_columns"
:local_key=
"form.local_key"
:local_key=
"form.local_key"
:edit_page=
"form.edit_page"
:edit_page=
"form.edit_page"
:checkbox=
"form.checkbox"
:checkbox=
"form.checkbox"
:edit_key=
"form.edit_key"
:edit_key=
"form.edit_key"
:table_api=
"form.table_api"
:table_api=
"form.table_api"
:table_num=
"table_num"
:filter_num=
"filter_num"
:filter_num=
"filter_num"
:filter_api=
"form.filter_api"
:filter_api=
"form.filter_api"
:AlreadyChoose=
"AlreadyChoose"
:AlreadyChoose=
"AlreadyChoose"
...
@@ -89,16 +90,21 @@
...
@@ -89,16 +90,21 @@
<
template
#
edit=
"{ row }"
>
<
template
#
edit=
"{ row }"
>
<slot
name=
"edit"
:row=
"row"
>
</slot>
<slot
name=
"edit"
:row=
"row"
>
</slot>
</
template
>
</
template
>
<
template
#
type=
"{ row }"
>
<slot
name=
"type"
:row=
"row"
>
</slot>
</
template
>
<
template
#
content=
"{ row }"
>
<
template
#
content=
"{ row }"
>
<slot
name=
"content"
:row=
"row"
></slot>
<slot
name=
"content"
:row=
"row"
></slot>
</
template
>
</
template
>
</CustomTable>
</CustomTable>
</div>
</div>
<slot></slot>
<slot></slot>
<CustomLoading
v-show=
"loading"
></CustomLoading>
</div>
</div>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
CustomLoading
from
'@/components/custom/loading2.vue'
;
import
TransitionView
from
'./TransitionView.vue'
;
import
TransitionView
from
'./TransitionView.vue'
;
import
RowPopup
from
'./RowPopup.vue'
;
import
RowPopup
from
'./RowPopup.vue'
;
import
CustomButtom
from
'./button.vue'
;
import
CustomButtom
from
'./button.vue'
;
...
@@ -111,6 +117,8 @@ import { getFilterParams } from '@/constants/admin_form';
...
@@ -111,6 +117,8 @@ import { getFilterParams } from '@/constants/admin_form';
import
CustomTable
from
'./table.vue'
;
import
CustomTable
from
'./table.vue'
;
import
{
onMounted
,
ref
}
from
'vue'
;
import
{
onMounted
,
ref
}
from
'vue'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
DataType
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
form
:
any
;
form
:
any
;
list
:
any
[];
list
:
any
[];
...
@@ -120,6 +128,9 @@ const store = useStore();
...
@@ -120,6 +128,9 @@ const store = useStore();
const
router
=
useRouter
();
const
router
=
useRouter
();
// 筛选盒子打开状态
// 筛选盒子打开状态
const
filterBoxStatus
=
ref
(
false
);
const
filterBoxStatus
=
ref
(
false
);
const
loading
=
ref
(
false
);
// 通知表格重新请求数据
const
table_num
=
ref
(
1
);
//
//
const
filter_num
=
ref
(
1
);
const
filter_num
=
ref
(
1
);
const
defaultWidth
=
ref
();
const
defaultWidth
=
ref
();
...
@@ -183,6 +194,40 @@ const onCreate = () => {
...
@@ -183,6 +194,40 @@ const onCreate = () => {
onMounted
(()
=>
{
onMounted
(()
=>
{
defaultWidth
.
value
=
adminFilter
.
value
.
offsetWidth
;
defaultWidth
.
value
=
adminFilter
.
value
.
offsetWidth
;
});
});
// 过滤出表格id
const
filterTableId
=
()
=>
{
const
is_array
=
DataType
(
'array'
,
SelectedRows
.
value
);
if
(
is_array
)
{
let
ids
=
''
;
// 开始过滤
SelectedRows
.
value
.
forEach
((
item
:
any
)
=>
{
if
(
item
.
id
)
{
ids
+=
item
.
id
+
''
+
','
;
}
});
return
ids
;
}
else
{
show_message
(
'格式错误'
);
}
};
// 多选事件触发
const
MultiSelectEvent
=
async
(
item
:
any
)
=>
{
if
(
item
.
value
==
'delete'
)
{
const
{
form
}
=
props
;
loading
.
value
=
true
;
const
ids
=
filterTableId
();
const
stauts
=
await
form
.
delete_api
({
ids
:
ids
,
});
loading
.
value
=
false
;
if
(
stauts
)
{
// 更新表格数据
table_num
.
value
+=
1
;
}
}
};
</
script
>
</
script
>
<
style
lang=
"less"
>
<
style
lang=
"less"
>
...
@@ -191,6 +236,7 @@ onMounted(() => {
...
@@ -191,6 +236,7 @@ onMounted(() => {
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
height
:
100%
;
height
:
100%
;
position
:
relative
;
.admin-page-header
{
.admin-page-header
{
display
:
flex
;
display
:
flex
;
justify-content
:
space-between
;
justify-content
:
space-between
;
...
...
src/components/Admin/CompleteAudio.vue
0 → 100644
View file @
581b5739
<
template
>
<div
class=
"audio-player-parent"
:style=
"
{
background: bk,
}"
>
<div
class=
"audio-player-left"
>
<template
v-if=
"content"
>
<div
class=
"audio-player-content"
>
{{
content
}}
</div>
</
template
>
<div
class=
"audio-player"
>
<img
v-show=
"!playStatus"
:src=
"imgs.start"
alt=
""
class=
"play-icon"
@
click=
"onPlay"
/>
<img
:src=
"imgs.stop"
alt=
""
class=
"play-icon"
@
click=
"onPause"
v-show=
"playStatus"
/>
<
template
v-if=
"need_progress"
>
<span
class=
"play-time"
>
{{
transTime
(
audioCurrent
)
}}
/
{{
transTime
(
audioDuration
)
}}
</span>
<div
class=
"play-progress"
>
<div
class=
"play-current-progress"
:style=
"
{ width: `${playProgress}%` }"
>
</div>
</div>
<!--
<img
src=
"@/assets/images/audio/voice-open.png"
alt=
""
class=
"play-voice"
v-if=
"audioVolume === 1"
@
click=
"onSetVolume(0)"
/>
<img
src=
"@/assets/images/audio/voice-close.png"
alt=
""
class=
"play-voice"
v-else
@
click=
"onSetVolume(1)"
/>
-->
</
template
>
</div>
</div>
<div
v-if=
"checkbox"
class=
"check-audio-box"
>
<TCheckbox
class=
"check-audio"
v-model=
"CheckStatus"
></TCheckbox>
</div>
<
template
v-for=
"(item, index) in url"
:key=
"item"
>
<template
v-if=
"index === 0"
>
<audio
ref=
"audioRef"
:src=
"CurrentUrl()"
></audio>
</
template
>
<
template
v-else
>
<audio
ref=
"audioRef"
:src=
"item"
></audio>
</
template
>
</template>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
Checkbox
as
TCheckbox
}
from
'tdesign-vue-next'
;
import
{
ref
,
onBeforeMount
,
watch
,
onMounted
,
onBeforeUnmount
,
computed
,
}
from
'vue'
;
import
{
DataType
}
from
'@/utils/tool'
;
/**
* 获取总长度并播放
*/
const
props
=
withDefaults
(
defineProps
<
{
modelValue
:
boolean
;
check_time
:
number
;
url
?:
string
[];
need_progress
?:
boolean
;
bk
?:
string
;
content
?:
string
;
checkbox
?:
boolean
;
}
>
(),
{
need_progress
:
false
,
url
:
()
=>
[],
bk
:
'transparent'
,
content
:
''
,
checkbox
:
false
,
}
);
const
emit
=
defineEmits
([
'update:modelValue'
,
'update:check_time'
]);
// 当前选中状态
const
CheckStatus
=
ref
(
props
.
modelValue
);
watch
(
()
=>
CheckStatus
.
value
,
(
v
)
=>
{
emit
(
'update:modelValue'
,
v
);
if
(
v
)
{
const
time
=
new
Date
().
valueOf
();
// 获取选中时间
emit
(
'update:check_time'
,
time
);
}
}
);
watch
(
()
=>
props
.
modelValue
,
(
v
)
=>
{
CheckStatus
.
value
=
v
;
}
);
const
imgs
=
{
start
:
new
URL
(
'../../assets/svg/admin/audioStart.svg'
,
import
.
meta
.
url
).
href
,
stop
:
new
URL
(
'../../assets/svg/admin/audioStop.svg'
,
import
.
meta
.
url
).
href
,
};
// 复制一份url列表,存储视频长度
const
copy_url_list
=
ref
(
new
Array
(
props
.
url
.
length
));
// 视频长度是否已存储
const
copy_audio_status
=
ref
(
false
);
const
speedList
=
[
{
label
:
'2x'
,
value
:
2
,
},
{
label
:
'1.5x'
,
value
:
1.5
,
},
{
label
:
'1x'
,
value
:
1
,
},
{
label
:
'0.75x'
,
value
:
0.75
,
},
];
onBeforeMount
(()
=>
{
clearInterval
(
timeInterval
.
value
);
});
onBeforeUnmount
(()
=>
{
clearInterval
(
timeInterval
.
value
);
});
const
speedVisible
=
ref
<
boolean
>
(
false
);
// 设置音频播放速度弹窗
const
audioRef
=
ref
();
// 音频标签对象
const
activeSpeed
=
ref
(
1
);
// 音频播放速度
const
audioCurrent
=
ref
(
0
);
// 音频当前播放时间
const
audioDuration
=
ref
(
0
);
// 音频总时长
const
audioVolume
=
ref
(
1
);
// 音频声音,范围 0-1
const
playStatus
=
ref
<
boolean
>
(
false
);
// 音频播放状态:true 播放,false 暂停
const
playProgress
=
ref
(
0
);
// 音频播放进度
const
timeInterval
=
ref
();
// 获取音频播放进度定时器
// 当前播放的音频下标
const
audio_index
=
ref
(
0
);
// 当前播放的音频链接
const
CurrentUrl
=
computed
(()
=>
{
return
function
()
{
const
{
url
}
=
props
;
if
(
url
&&
url
.
length
)
{
return
url
[
audio_index
.
value
];
}
};
});
// 获取音频播放总时长
const
getAudioDuration
=
()
=>
{
audioDuration
.
value
=
0
;
// ref是个列表
if
(
audioRef
.
value
&&
audioRef
.
value
.
length
)
{
for
(
let
i
=
0
;
i
<
audioRef
.
value
.
length
;
i
++
)
{
const
item
=
audioRef
.
value
[
i
];
audioDuration
.
value
+=
item
.
duration
||
0
;
}
}
else
{
audioDuration
.
value
=
audioRef
?.
value
.
duration
||
0
;
}
};
// 获取音频播放进度
const
getCurrentAudioTime
=
()
=>
{
audioCurrent
.
value
=
0
;
const
index
=
audio_index
.
value
;
const
status
=
DataType
(
'array'
,
audioRef
.
value
);
if
(
status
)
{
// 是数组
for
(
let
i
=
0
;
i
<
audioRef
.
value
.
length
;
i
++
)
{
const
item
=
audioRef
.
value
[
i
];
if
(
i
<
index
)
{
// +总进度
audioCurrent
.
value
+=
copy_url_list
.
value
[
i
];
}
else
if
(
i
==
index
)
{
if
(
index
==
0
)
{
// 第一个
audioCurrent
.
value
=
item
.
currentTime
;
}
else
{
// 其他
audioCurrent
.
value
+=
audioRef
.
value
[
0
].
currentTime
;
}
}
}
}
else
{
audioCurrent
.
value
=
audioRef
.
value
.
currentTime
;
}
};
// 音频列表时长是否全部为number类型
const
AllAudioListDuration
=
(
list
:
any
[])
=>
{
let
status
=
true
;
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
const
item
=
list
[
i
];
if
(
typeof
item
!==
'number'
)
{
status
=
false
;
break
;
}
}
return
status
;
};
// 音频加载完毕的回调
const
onCanplay
=
()
=>
{
const
status
=
DataType
(
'array'
,
audioRef
.
value
);
if
(
status
)
{
// 是数组
audioRef
.
value
.
forEach
((
item
:
HTMLAudioElement
,
index
:
number
)
=>
{
item
.
oncanplay
=
function
(
e
:
any
)
{
// 判断是否全部为number类型
if
(
!
copy_audio_status
.
value
)
{
copy_url_list
.
value
[
index
]
=
item
.
duration
;
let
is_number
=
AllAudioListDuration
(
copy_url_list
.
value
);
if
(
is_number
)
{
// 计算总量
getAudioDuration
();
copy_audio_status
.
value
=
true
;
}
}
};
});
}
};
onMounted
(()
=>
{
//
onCanplay
();
});
// 更新音频
const
UpdateAudio
=
async
()
=>
{
// 进入到下一个
const
{
url
}
=
props
;
if
(
url
&&
url
.
length
)
{
if
(
audio_index
.
value
===
url
.
length
-
1
)
{
// 最后一个,暂停播放
await
onPause
();
audio_index
.
value
=
0
;
}
else
if
(
audio_index
.
value
<
url
.
length
-
1
)
{
audio_index
.
value
+=
1
;
await
onPause
(
false
);
onPlay
();
}
}
};
const
onPlay
=
async
()
=>
{
// 音频播放完后,重新播放
if
(
playProgress
.
value
>=
100
)
{
audio_index
.
value
=
0
;
audioRef
.
value
[
0
].
currentTime
=
0
;
}
const
status
=
DataType
(
'array'
,
audioRef
.
value
);
if
(
status
)
{
await
audioRef
.
value
[
0
].
play
();
}
else
{
await
audioRef
.
value
.
play
();
}
playStatus
.
value
=
true
;
timeInterval
.
value
=
setInterval
(()
=>
{
// 当前进度需要根据当前下标累加
getCurrentAudioTime
();
playProgress
.
value
=
(
audioCurrent
.
value
/
audioDuration
.
value
)
*
100
;
const
status
=
DataType
(
'array'
,
audioRef
.
value
);
if
(
status
)
{
const
playRef
=
audioRef
.
value
[
0
];
// 是数组
if
(
playRef
.
currentTime
==
playRef
.
duration
)
{
UpdateAudio
();
}
}
else
if
(
playProgress
.
value
===
100
)
{
// 只有一个
UpdateAudio
();
}
},
100
);
};
// 暂停播放
const
onPause
=
async
(
changeStatus
:
boolean
=
true
)
=>
{
const
status
=
DataType
(
'array'
,
audioRef
.
value
);
if
(
status
)
{
await
audioRef
.
value
[
0
].
pause
();
}
else
{
await
audioRef
.
value
.
pause
();
}
if
(
changeStatus
)
{
playStatus
.
value
=
false
;
}
clearInterval
(
timeInterval
.
value
);
};
const
onChangeSpeed
=
(
value
:
number
)
=>
{
activeSpeed
.
value
=
value
;
// 设置倍速
audioRef
.
value
.
playbackRate
=
value
;
speedVisible
.
value
=
false
;
};
const
onHandleSpeed
=
()
=>
{
speedVisible
.
value
=
!
speedVisible
.
value
;
};
// 设置声音
const
onSetVolume
=
(
value
:
number
)
=>
{
audioRef
.
value
.
volume
=
value
;
audioVolume
.
value
=
value
;
};
// 音频播放时间换算
const
transTime
=
(
value
:
number
)
=>
{
let
time
=
''
;
let
h
=
parseInt
(
String
(
value
/
3600
));
value
%=
3600
;
let
m
=
parseInt
(
String
(
value
/
60
));
let
s
=
parseInt
(
String
(
value
%
60
));
if
(
h
>
0
)
{
time
=
formatTime
(
h
+
':'
+
m
+
':'
+
s
);
}
else
{
time
=
formatTime
(
m
+
':'
+
s
);
}
return
time
;
};
// 格式化时间显示,补零对齐
const
formatTime
=
(
value
:
string
)
=>
{
let
time
=
''
;
let
s
=
value
.
split
(
':'
);
let
i
=
0
;
for
(;
i
<
s
.
length
-
1
;
i
++
)
{
time
+=
s
[
i
].
length
==
1
?
'0'
+
s
[
i
]
:
s
[
i
];
time
+=
':'
;
}
time
+=
s
[
i
].
length
==
1
?
'0'
+
s
[
i
]
:
s
[
i
];
return
time
;
};
</
script
>
<
style
lang=
"less"
scoped
>
@import
'@/style/variables'
;
.audio-player-parent
{
border-radius
:
8px
;
padding
:
0
12px
;
display
:
flex
;
.audio-player-left
{
max-width
:
92%
;
}
.check-audio-box
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
flex
:
1
;
:deep(.check-audio)
{
.t-checkbox__input
{
border
:
1px
solid
#ffffff
;
border-radius
:
2px
;
background
:
transparent
;
}
}
.t-is-checked
{
.t-checkbox__input
{
border
:
1px
solid
@
main-color-1
;
background
:
@
main-color-1
;
&::after
{
border-color
:
black
;
}
}
}
}
.audio-player-content
{
max-width
:
100%
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
padding
:
16px
12px
6px
12px
;
}
.audio-player
{
height
:
52px
;
box-sizing
:
border-box
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
margin-left
:
6px
;
margin-bottom
:
8px
;
.play-icon
{
width
:
34px
;
height
:
34px
;
cursor
:
pointer
;
}
.play-time
{
width
:
72px
;
display
:
inline-block
;
margin
:
0
16px
;
font-weight
:
400
;
font-size
:
14px
;
}
.play-progress
{
flex
:
1
;
height
:
4px
;
background
:
#2d2d2d
;
box-shadow
:
inset
0px
1px
0px
0px
#20222d
;
border-radius
:
2px
;
margin-right
:
16px
;
position
:
relative
;
.play-current-progress
{
height
:
4px
;
background
:
#00e5ff
;
border-radius
:
2px
;
position
:
absolute
;
top
:
0
;
left
:
0
;
}
}
.play-voice
{
width
:
20px
;
height
:
20px
;
margin-right
:
14px
;
cursor
:
pointer
;
}
.play-speed
{
cursor
:
pointer
;
color
:
#00e5ff
;
}
}
}
</
style
>
src/components/Admin/GenerateVoice.vue
View file @
581b5739
<
template
>
<
template
>
<div
class=
""
>
<div
v-for=
"item in list"
:key=
"item.hash"
class=
"edit-audio-result"
>
<template
v-if=
"status === 'true'"
>
<template
v-if=
"item.status"
>
<CustomAudio
bk=
"#181818"
:need_progress=
"true"
:url=
"url"
></CustomAudio>
<CompleteAudio
v-model=
"item.is_check"
v-model:check_time=
"item.check_time"
bk=
"#181818"
:need_progress=
"true"
:url=
"item.audio"
:content=
"item.content"
:checkbox=
"true"
></CompleteAudio>
</
template
>
</
template
>
<
template
v-else
-if=
"status === 'false'"
>
<
template
v-else
>
<!-- loading -->
<!-- loading -->
<div
class=
"voice-loading"
>
<div
class=
"voice-loading"
>
<DotLoop>
语音正在生成中,请耐心等待
</DotLoop>
<DotLoop>
语音正在生成中,请耐心等待
</DotLoop>
...
@@ -13,28 +21,55 @@
...
@@ -13,28 +21,55 @@
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
CustomAudio
from
'./audio.vue'
;
import
{
ref
,
watch
}
from
'vue'
;
import
CompleteAudio
from
'./CompleteAudio.vue'
;
import
DotLoop
from
'./DotLoop.vue'
;
import
DotLoop
from
'./DotLoop.vue'
;
const
props
=
withDefaults
(
const
props
=
withDefaults
(
defineProps
<
{
defineProps
<
{
status
:
string
;
list
:
any
[];
url
?:
any
[];
}
>
(),
}
>
(),
{
{}
url
:
()
=>
[],
}
);
);
// 修改item——check状态
const
ChangeList
=
(
list
:
any
[])
=>
{
// 找到最大的时间戳
let
max_time
=
0
;
list
.
forEach
((
item
:
any
)
=>
{
if
(
item
.
check_time
&&
item
.
check_time
>
max_time
&&
item
.
is_check
)
{
max_time
=
item
.
check_time
;
}
});
const
index
=
list
.
findIndex
((
item
:
any
)
=>
item
.
check_time
===
max_time
);
if
(
index
!==
-
1
)
{
// 将其他 is_check 修改为false
list
.
forEach
((
item
:
any
,
id
:
number
)
=>
{
if
(
index
!==
id
)
{
item
.
is_check
=
false
;
}
});
}
};
// 当前选择的语音
const
CurrentVoice
=
ref
(
''
);
watch
(
props
.
list
,
(
v
)
=>
{
ChangeList
(
v
);
});
</
script
>
</
script
>
<
style
lang=
"less"
>
<
style
lang=
"less"
>
.voice-loading
{
.voice-loading
{
background
:
#181818
;
background
:
#181818
;
border-radius
:
42
px
;
border-radius
:
8
px
;
font-weight
:
400
;
font-weight
:
400
;
font-size
:
13px
;
font-size
:
13px
;
height
:
54
px
;
height
:
103
px
;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
;
}
}
.edit-audio-result
:not
(
:first-child
)
{
margin-top
:
12px
;
}
</
style
>
</
style
>
src/components/Admin/PageEdit.vue
View file @
581b5739
...
@@ -19,8 +19,8 @@
...
@@ -19,8 +19,8 @@
</
template
>
</
template
>
</CustomButton>
</CustomButton>
</template>
</template>
<
template
v-if=
"form.delete"
>
<
template
v-if=
"form.delete
_api
"
>
<CustomButton
class=
"body-head-btn"
<CustomButton
class=
"body-head-btn"
@
click=
"onDelete"
>
删除
>
删除
<template
#
icon
>
<template
#
icon
>
<DeleteSvg></DeleteSvg>
<DeleteSvg></DeleteSvg>
...
@@ -122,7 +122,7 @@
...
@@ -122,7 +122,7 @@
</template>
</template>
<
template
v-if=
"form.conversion"
>
<
template
v-if=
"form.conversion"
>
<div
class=
"conversion-box"
>
<div
class=
"conversion-box"
>
<CustomButton
class=
"edit-conversion-btn"
<CustomButton
class=
"edit-conversion-btn"
@
click=
"StartConvert"
>
转换为语音
>
转换为语音
<template
#
icon
>
<template
#
icon
>
<span
class=
"conversion-icon"
>
<span
class=
"conversion-icon"
>
...
@@ -131,12 +131,7 @@
...
@@ -131,12 +131,7 @@
</
template
>
</
template
>
</CustomButton>
</CustomButton>
</div>
</div>
</template>
<GenerateVoice
:list=
"form.conversion.list"
></GenerateVoice>
<
template
v-if=
"form.audio"
>
<GenerateVoice
:status=
"form.audio.status"
:url=
"form.audio.url"
></GenerateVoice>
</template>
</template>
<
template
v-if=
"form.start_broadcast"
>
<
template
v-if=
"form.start_broadcast"
>
<StartBroadcast
:status=
"'not_on_air'"
></StartBroadcast>
<StartBroadcast
:status=
"'not_on_air'"
></StartBroadcast>
...
@@ -161,14 +156,24 @@
...
@@ -161,14 +156,24 @@
<
template
v-if=
"form.reset"
>
<
template
v-if=
"form.reset"
>
<CustomButton
class=
"edit-footer-btn reset"
>
重置
</CustomButton>
<CustomButton
class=
"edit-footer-btn reset"
>
重置
</CustomButton>
</
template
>
</
template
>
<
template
v-if=
"form.submit"
>
<
template
v-if=
"form.submit_api"
>
<CustomButton
class=
"edit-footer-btn submit"
>
提交
</CustomButton>
<CustomButton
class=
"edit-footer-btn submit"
@
click=
"onSubmit"
>
提交
</CustomButton
>
</
template
>
</
template
>
</div>
</div>
<CustomLoading
v-show=
"loading"
></CustomLoading>
<ConfirmDialog
v-model=
"dialog_visible"
:label=
"'删除'"
@
confirm=
"deleteConfirm"
></ConfirmDialog>
</div>
</div>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
ConfirmDialog
from
'./ConfirmDialog.vue'
;
import
CustomLoading
from
'@/components/custom/loading2.vue'
;
import
GenerateVoice
from
'./GenerateVoice.vue'
;
import
GenerateVoice
from
'./GenerateVoice.vue'
;
import
CustomButton
from
'./button.vue'
;
import
CustomButton
from
'./button.vue'
;
import
CustomTextarea
from
'./Textarea.vue'
;
import
CustomTextarea
from
'./Textarea.vue'
;
...
@@ -185,11 +190,15 @@ import DiscourseBindSvg from '@/assets/svg/form/discourseBind.svg';
...
@@ -185,11 +190,15 @@ import DiscourseBindSvg from '@/assets/svg/form/discourseBind.svg';
import
ManualResponseSvg
from
'@/assets/svg/form/ManualResponse.svg'
;
import
ManualResponseSvg
from
'@/assets/svg/form/ManualResponse.svg'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
getFormParams
}
from
'@/constants/admin_form'
;
import
{
ref
}
from
'vue'
;
import
{
ref
}
from
'vue'
;
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
form
:
any
;
form
:
any
;
}
>
();
}
>
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
loading
=
ref
(
false
);
// 弹窗状态
const
dialog_visible
=
ref
(
false
);
const
backTable
=
()
=>
{
const
backTable
=
()
=>
{
const
{
back_url
}
=
props
.
form
;
const
{
back_url
}
=
props
.
form
;
...
@@ -215,6 +224,55 @@ const onSend = () => {
...
@@ -215,6 +224,55 @@ const onSend = () => {
const
SelectChange
=
(
value
:
string
,
fun
:
any
)
=>
{
const
SelectChange
=
(
value
:
string
,
fun
:
any
)
=>
{
fun
(
value
);
fun
(
value
);
};
};
// 开始转换语音
const
StartConvert
=
()
=>
{
const
{
form
}
=
props
;
// 校验表单完整性
let
params
=
getFormParams
(
form
.
form_options
);
if
(
!
params
)
{
return
;
}
form
.
conversion
.
method
(
params
,
form
.
page_name
);
};
// 提交接口
const
onSubmit
=
async
()
=>
{
const
{
form
}
=
props
;
loading
.
value
=
true
;
await
form
.
submit_api
();
loading
.
value
=
false
;
};
// 弹窗确认事件
const
deleteConfirm
=
()
=>
{
realDelete
();
};
//
const
realDelete
=
async
()
=>
{
const
{
form
}
=
props
;
loading
.
value
=
true
;
// 获取当前id
await
form
.
delete_api
(
{
ids
:
form
.
get_id
(),
},
form
.
back_url
);
loading
.
value
=
false
;
};
// 删除单个
const
onDelete
=
async
()
=>
{
const
{
form
}
=
props
;
if
(
form
.
delete_confirm
)
{
// 打开确认弹窗
dialog_visible
.
value
=
true
;
}
else
{
realDelete
();
}
};
</
script
>
</
script
>
<
style
lang=
"less"
>
<
style
lang=
"less"
>
...
@@ -223,6 +281,7 @@ const SelectChange = (value: string, fun: any) => {
...
@@ -223,6 +281,7 @@ const SelectChange = (value: string, fun: any) => {
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
height
:
100%
;
height
:
100%
;
position
:
relative
;
.custom-admin-page-edit
{
.custom-admin-page-edit
{
flex
:
1
;
flex
:
1
;
padding
:
20px
30px
30px
30px
;
padding
:
20px
30px
30px
30px
;
...
@@ -283,10 +342,11 @@ const SelectChange = (value: string, fun: any) => {
...
@@ -283,10 +342,11 @@ const SelectChange = (value: string, fun: any) => {
flex
:
1
;
flex
:
1
;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
padding
:
0
30px
;
padding
:
0
30px
20px
30px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
.edit-form-content
{
.edit-form-content
{
width
:
800px
;
width
:
100%
;
max-width
:
800px
;
.edit-form-item-label
{
.edit-form-item-label
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
...
@@ -368,6 +428,7 @@ const SelectChange = (value: string, fun: any) => {
...
@@ -368,6 +428,7 @@ const SelectChange = (value: string, fun: any) => {
}
}
.admin-edit-footer
{
.admin-edit-footer
{
height
:
60px
;
height
:
60px
;
min-height
:
60px
;
background
:
#2d2d2d
;
background
:
#2d2d2d
;
display
:
flex
;
display
:
flex
;
justify-content
:
flex-end
;
justify-content
:
flex-end
;
...
...
src/components/Admin/RowPopup.vue
View file @
581b5739
...
@@ -80,7 +80,7 @@ const RowClick = (item: any) => {
...
@@ -80,7 +80,7 @@ const RowClick = (item: any) => {
// 点击了确认
// 点击了确认
const
DialogConfirm
=
()
=>
{
const
DialogConfirm
=
()
=>
{
console
.
log
(
current_params
.
value
);
emit
(
'change'
,
current_params
.
value
);
};
};
</
script
>
</
script
>
...
...
src/components/Admin/Textarea.vue
View file @
581b5739
...
@@ -11,7 +11,9 @@
...
@@ -11,7 +11,9 @@
}"
}"
>
</TTextarea>
>
</TTextarea>
<div
class=
"position-text"
>
<div
class=
"position-text"
>
<span>
{{
textareaLength
}}
/
{{
maxlength
}}
</span>
|
<template
v-if=
"maxlength"
>
<span>
{{
textareaLength
}}
/
{{
maxlength
}}
</span>
|
</
template
>
<span
class=
"reset-btn"
@
click=
"reset"
>
清空
</span>
<span
class=
"reset-btn"
@
click=
"reset"
>
清空
</span>
</div>
</div>
<
template
v-if=
"disabled"
>
<
template
v-if=
"disabled"
>
...
@@ -39,7 +41,6 @@ const props = withDefaults(
...
@@ -39,7 +41,6 @@ const props = withDefaults(
placeholder
:
'请输入'
,
placeholder
:
'请输入'
,
maxRows
:
5
,
maxRows
:
5
,
minRows
:
5
,
minRows
:
5
,
maxlength
:
500
,
disabled
:
false
,
disabled
:
false
,
}
}
);
);
...
@@ -47,7 +48,7 @@ const emit = defineEmits(['update:modelValue']);
...
@@ -47,7 +48,7 @@ const emit = defineEmits(['update:modelValue']);
const
imgs
=
{
const
imgs
=
{
disabled
:
new
URL
(
'../../assets/svg/form/disabled.svg'
,
import
.
meta
.
url
).
href
,
disabled
:
new
URL
(
'../../assets/svg/form/disabled.svg'
,
import
.
meta
.
url
).
href
,
};
};
const
textarea_value
=
ref
(
''
);
const
textarea_value
=
ref
(
props
.
modelValue
);
const
reset
=
()
=>
{
const
reset
=
()
=>
{
textarea_value
.
value
=
''
;
textarea_value
.
value
=
''
;
};
};
...
...
src/components/Admin/audio.vue
View file @
581b5739
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
ref
,
onBeforeMount
,
onBeforeUnmount
,
computed
}
from
'vue'
;
import
{
ref
,
onBeforeMount
,
onBeforeUnmount
,
computed
,
watch
}
from
'vue'
;
const
props
=
withDefaults
(
const
props
=
withDefaults
(
defineProps
<
{
defineProps
<
{
...
@@ -58,6 +58,7 @@ const props = withDefaults(
...
@@ -58,6 +58,7 @@ const props = withDefaults(
bk
:
'transparent'
,
bk
:
'transparent'
,
}
}
);
);
const
imgs
=
{
const
imgs
=
{
start
:
new
URL
(
'../../assets/svg/admin/audioStart.svg'
,
import
.
meta
.
url
).
href
,
start
:
new
URL
(
'../../assets/svg/admin/audioStart.svg'
,
import
.
meta
.
url
).
href
,
stop
:
new
URL
(
'../../assets/svg/admin/audioStop.svg'
,
import
.
meta
.
url
).
href
,
stop
:
new
URL
(
'../../assets/svg/admin/audioStop.svg'
,
import
.
meta
.
url
).
href
,
...
@@ -103,6 +104,12 @@ const timeInterval = ref(); // 获取音频播放进度定时器
...
@@ -103,6 +104,12 @@ const timeInterval = ref(); // 获取音频播放进度定时器
// 当前播放的音频下标
// 当前播放的音频下标
const
audio_index
=
ref
(
0
);
const
audio_index
=
ref
(
0
);
watch
(
props
.
url
,
(
v
)
=>
{
// 重新初始化音频
audio_index
.
value
=
0
;
audioCurrent
.
value
=
0
;
onPause
();
});
// 当前播放的音频链接
// 当前播放的音频链接
const
CurrentUrl
=
computed
(()
=>
{
const
CurrentUrl
=
computed
(()
=>
{
return
function
()
{
return
function
()
{
...
...
src/components/Admin/table.vue
View file @
581b5739
...
@@ -8,18 +8,22 @@
...
@@ -8,18 +8,22 @@
:loading=
"loading"
:loading=
"loading"
>
>
<template
#
check_all
>
<template
#
check_all
>
<TCheckbox
<template
v-if=
"checkbox"
>
class=
"check-all-box"
<TCheckbox
v-model=
"is_check_all"
class=
"check-all-box"
@
change=
"CheckAll"
v-model=
"is_check_all"
></TCheckbox>
@
change=
"CheckAll"
></TCheckbox>
</
template
>
</template>
</template>
<
template
#
checkbox=
"{ row }"
>
<
template
#
checkbox=
"{ row }"
>
<TCheckbox
<template
v-if=
"checkbox"
>
v-model=
"row.is_check"
<TCheckbox
class=
"check-all-box"
v-model=
"row.is_check"
@
change=
"CheckOne(row)"
class=
"check-all-box"
></TCheckbox>
@
change=
"CheckOne(row)"
></TCheckbox>
</
template
>
</template>
</template>
<
template
#
audio=
"{ row }"
>
<
template
#
audio=
"{ row }"
>
<slot
name=
"audio"
:row=
"row"
></slot>
<slot
name=
"audio"
:row=
"row"
></slot>
...
@@ -27,6 +31,14 @@
...
@@ -27,6 +31,14 @@
<
template
#
content=
"{ row }"
>
<
template
#
content=
"{ row }"
>
<slot
name=
"content"
:row=
"row"
></slot>
<slot
name=
"content"
:row=
"row"
></slot>
</
template
>
</
template
>
<
template
#
language=
"{ row }"
>
{{
language_type
[
row
.
language
]
}}
</
template
>
<
template
#
type=
"{ row }"
>
<slot
name=
"type"
:row=
"row"
>
{{
row
.
type
}}
</slot>
</
template
>
<
template
#
edit=
"{ row }"
>
<
template
#
edit=
"{ row }"
>
<slot
name=
"edit"
:row=
"row"
>
<slot
name=
"edit"
:row=
"row"
>
<span
class=
"edit-text"
@
click=
"onEdit(row)"
>
编辑
</span>
<span
class=
"edit-text"
@
click=
"onEdit(row)"
>
编辑
</span>
...
@@ -52,7 +64,7 @@ import { onBeforeMount, reactive, ref, watch } from 'vue';
...
@@ -52,7 +64,7 @@ import { onBeforeMount, reactive, ref, watch } from 'vue';
import
{
Pagination
as
TPagination
}
from
'tdesign-vue-next'
;
import
{
Pagination
as
TPagination
}
from
'tdesign-vue-next'
;
// import { TASKTYPE } from '@/utils/api/Task';
// import { TASKTYPE } from '@/utils/api/Task';
import
{
getLocalData
,
setLocalData
}
from
'@/utils/tool'
;
import
{
getLocalData
,
setLocalData
}
from
'@/utils/tool'
;
import
{
EditButtonEvent
}
from
'@/constants/admin_form'
;
import
{
EditButtonEvent
,
language_type
}
from
'@/constants/admin_form'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
const
props
=
withDefaults
(
const
props
=
withDefaults
(
defineProps
<
{
defineProps
<
{
...
@@ -65,6 +77,7 @@ const props = withDefaults(
...
@@ -65,6 +77,7 @@ const props = withDefaults(
filter_num
?:
number
;
filter_num
?:
number
;
filter_api
?:
any
;
filter_api
?:
any
;
AlreadyChoose
?:
any
;
AlreadyChoose
?:
any
;
table_num
?:
number
;
}
>
(),
}
>
(),
{
{
checkbox
:
true
,
checkbox
:
true
,
...
@@ -72,6 +85,7 @@ const props = withDefaults(
...
@@ -72,6 +85,7 @@ const props = withDefaults(
filter_num
:
1
,
filter_num
:
1
,
filter_api
:
false
,
filter_api
:
false
,
AlreadyChoose
:
{},
AlreadyChoose
:
{},
table_num
:
1
,
}
}
);
);
const
emit
=
defineEmits
([
'ChangeList'
,
'ChoseList'
,
'PageNumChange'
]);
const
emit
=
defineEmits
([
'ChangeList'
,
'ChoseList'
,
'PageNumChange'
]);
...
@@ -147,11 +161,13 @@ const CheckOne = (row: any) => {
...
@@ -147,11 +161,13 @@ const CheckOne = (row: any) => {
// 添加表格多选框和状态
// 添加表格多选框和状态
const
setTableCheckBox
=
(
res
:
any
)
=>
{
const
setTableCheckBox
=
(
res
:
any
)
=>
{
// 增加一个选中状态
if
(
props
.
checkbox
)
{
res
.
list
.
forEach
((
item
:
any
,
index
:
number
)
=>
{
// 增加一个选中状态
item
.
is_check
=
false
;
res
.
list
.
forEach
((
item
:
any
,
index
:
number
)
=>
{
item
.
index
=
index
;
item
.
is_check
=
false
;
});
item
.
index
=
index
;
});
}
return
res
;
return
res
;
};
};
...
@@ -183,6 +199,13 @@ watch(
...
@@ -183,6 +199,13 @@ watch(
StartFilter
();
StartFilter
();
}
}
);
);
watch
(
()
=>
props
.
table_num
,
(
v
)
=>
{
ChangeCurrentPage
(
1
);
getLog
();
}
);
// 打开编辑页面
// 打开编辑页面
const
onEdit
=
(
row
:
any
)
=>
{
const
onEdit
=
(
row
:
any
)
=>
{
...
@@ -195,9 +218,7 @@ const getLog = async () => {
...
@@ -195,9 +218,7 @@ const getLog = async () => {
try
{
try
{
loading
.
value
=
true
;
loading
.
value
=
true
;
let
res
:
any
=
await
props
.
table_api
();
let
res
:
any
=
await
props
.
table_api
();
if
(
props
.
checkbox
)
{
res
=
await
setTableCheckBox
(
res
);
res
=
await
setTableCheckBox
(
res
);
}
tableList
.
list
=
res
.
list
;
tableList
.
list
=
res
.
list
;
total
.
value
=
res
.
total
;
total
.
value
=
res
.
total
;
loading
.
value
=
false
;
loading
.
value
=
false
;
...
...
src/constants/admin_form.ts
View file @
581b5739
import
{
getLocalData
,
setLocalData
}
from
'@/utils/tool'
;
import
{
getLocalData
,
setLocalData
}
from
'@/utils/tool'
;
import
router
from
'@/router'
;
import
router
from
'@/router'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
Validationrules
}
from
'@/utils/tool'
;
// 语言列表
import
{
DeleteVioce
}
from
'@/utils/api/ai'
;
// 语音列表
export
const
voice_list
=
[
export
const
voice_list
=
[
{
{
label
:
'柜姐'
,
label
:
'柜姐'
,
value
:
'guijie'
,
value
:
'guijie'
,
// 试听
audio
:
{
cn
:
'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/74843270679d44e0a6a5692e972a16a0_0.mp3'
,
en
:
''
,
},
},
},
{
{
label
:
'小仙'
,
label
:
'小仙'
,
value
:
'xiaoxian'
,
value
:
'xiaoxian'
,
audio
:
{
cn
:
'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/39c3b915dbbc4989aeda4a259a8fd477_0.mp3'
,
en
:
''
,
},
},
},
{
{
label
:
'艾飞'
,
label
:
'艾飞'
,
value
:
'aifei'
,
value
:
'aifei'
,
audio
:
{
cn
:
'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/6efdfd4a9356462993fbe53ee2c30588_0.mp3'
,
en
:
''
,
},
},
},
{
{
label
:
'老铁'
,
label
:
'老铁'
,
value
:
'laotie'
,
value
:
'laotie'
,
audio
:
{
cn
:
'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/09adc64844044bf2afdc1861b4c73dad_0.mp3'
,
en
:
''
,
},
},
},
{
{
label
:
'老妹'
,
label
:
'老妹'
,
value
:
'laomei'
,
value
:
'laomei'
,
audio
:
{
cn
:
'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/da1829e4089b40d9b50faa2b973a7c15_0.mp3'
,
en
:
''
,
},
},
},
];
];
// 语言列表
export
const
language_list
=
[
{
label
:
'中文'
,
value
:
'cn'
,
},
{
label
:
'英文'
,
value
:
'en'
,
},
];
// 语言类型
export
const
language_type
=
{
cn
:
'中文'
,
en
:
'英文'
,
};
// 互动类型
export
const
interaction_type
=
{
'0'
:
'直播互动'
,
'1'
:
'自动回复'
,
};
// 任务类型
export
const
admin_task_type
=
{
dialogues
:
'dialogues'
,
// 话术管理
interaction
:
'interaction'
,
// 互动设置
};
// 获取form表单的值
export
const
getFormParams
=
(
list
:
any
[])
=>
{
const
params
:
any
=
{};
// 遍历整个列表
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
const
item
:
any
=
list
[
i
];
for
(
let
j
=
0
;
j
<
item
.
lists
.
length
;
j
++
)
{
const
it
=
item
.
lists
[
j
];
// 校验规则
const
message
=
Validationrules
(
it
.
rules
,
it
.
value
,
it
.
name
);
if
(
message
)
{
// 提示错误信息
show_message
(
message
);
return
false
;
}
else
{
if
(
it
.
name
==
'number'
)
{
// 转换为number类型
params
[
it
.
name
]
=
parseFloat
(
it
.
value
+
''
);
}
else
{
// 添加params
params
[
it
.
name
]
=
it
.
value
;
}
}
}
}
return
params
;
};
// 清空admin-form的value值
// 清空admin-form的value值
export
const
ResetForm
=
(
list
:
any
[])
=>
{
export
const
ResetForm
=
(
list
:
any
[])
=>
{
list
.
forEach
((
item
:
any
)
=>
{
list
.
forEach
((
item
:
any
)
=>
{
...
@@ -80,16 +160,13 @@ export const EditFillData = (form: any[], row: any) => {
...
@@ -80,16 +160,13 @@ export const EditFillData = (form: any[], row: any) => {
item
.
lists
.
forEach
((
it
:
any
)
=>
{
item
.
lists
.
forEach
((
it
:
any
)
=>
{
// 查找name相同的字段
// 查找name相同的字段
Object
.
keys
(
row
).
forEach
((
key
:
string
)
=>
{
Object
.
keys
(
row
).
forEach
((
key
:
string
)
=>
{
// console.log(value);
if
(
it
.
name
==
key
)
{
if
(
it
.
name
==
key
)
{
console
.
log
(
it
.
name
);
// 填充数据
// 填充数据
it
.
value
=
row
[
key
]
+
''
;
it
.
value
=
row
[
key
]
+
''
;
}
}
});
});
});
});
});
});
console
.
log
(
form
);
};
};
// 筛选配置填充
// 筛选配置填充
...
@@ -116,3 +193,24 @@ export const FilterConfigFill = (resData: any, form: any[]) => {
...
@@ -116,3 +193,24 @@ export const FilterConfigFill = (resData: any, form: any[]) => {
});
});
});
});
};
};
// 话术管理删除
export
const
DiscourseManagementDelete
=
async
(
data
:
any
,
path
:
string
=
''
)
=>
{
try
{
const
res
:
any
=
await
DeleteVioce
(
data
);
if
(
res
.
code
==
0
)
{
show_message
(
'删除成功'
,
'success'
);
if
(
path
)
{
router
.
replace
({
path
:
path
,
});
}
return
true
;
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
src/hooks/ConvertVoice.ts
0 → 100644
View file @
581b5739
import
{
DiscourseManagementConvertTask
,
ConvertTaskResponse
,
SubmitTaskInteract
,
QueryInteractResponse
,
}
from
'@/utils/api/ai'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
onBeforeUnmount
,
reactive
,
ref
}
from
'vue'
;
import
{
admin_task_type
}
from
'@/constants/admin_form'
;
export
default
function
()
{
let
Interval
:
any
=
null
;
const
status
=
ref
(
true
);
// 已返回的语音列表
const
CurrentVoice
=
reactive
({
list
:
[]
as
any
[],
});
// 轮询获取语音转换返回值
const
getVoiceResponse
=
async
(
hash
:
string
,
content
:
string
,
name
:
string
)
=>
{
try
{
let
res
:
any
=
null
;
if
(
name
===
admin_task_type
.
dialogues
)
{
// 话术管理
res
=
await
ConvertTaskResponse
({
hash
:
hash
,
});
}
else
if
(
name
===
admin_task_type
.
interaction
)
{
// 互动设置
res
=
await
QueryInteractResponse
({
hash
:
hash
,
});
}
if
(
res
.
code
==
0
&&
res
.
data
&&
res
.
data
.
audio
)
{
// 找到列表中对应的hash
CurrentVoice
.
list
.
forEach
((
item
:
any
)
=>
{
if
(
item
.
hash
===
hash
)
{
item
.
status
=
true
;
item
.
audio
=
typeof
res
.
data
.
audio
===
'string'
?
JSON
.
parse
(
res
.
data
.
audio
)
:
res
.
data
.
audio
;
item
.
content
=
content
;
}
});
console
.
log
(
CurrentVoice
.
list
);
// 关闭定时器
closeInterval
();
status
.
value
=
true
;
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 打开定时器
const
openInterval
=
(
hash
:
string
,
content
:
string
,
name
:
string
)
=>
{
Interval
=
window
.
setInterval
(()
=>
{
getVoiceResponse
(
hash
,
content
,
name
);
},
3000
);
};
// 关闭定时器
const
closeInterval
=
()
=>
{
if
(
Interval
)
{
window
.
clearInterval
(
Interval
);
Interval
=
null
;
}
};
// 提交语音转换任务
const
SubmitConvertTask
=
async
(
data
:
any
,
name
:
string
)
=>
{
try
{
if
(
!
status
.
value
)
{
// 上个任务未完成
show_message
(
'请等待上个任务完成'
);
return
;
}
status
.
value
=
false
;
let
res
:
any
=
null
;
if
(
name
===
admin_task_type
.
dialogues
)
{
// 话术管理
res
=
await
DiscourseManagementConvertTask
(
data
);
}
else
if
(
name
===
admin_task_type
.
interaction
)
{
// 互动设置
res
=
await
SubmitTaskInteract
(
data
);
}
//
if
(
res
.
code
==
0
&&
res
.
data
.
hash
)
{
CurrentVoice
.
list
.
unshift
({
hash
:
res
.
data
.
hash
,
status
:
false
,
audio
:
[],
content
:
''
,
// 是否选中
is_check
:
false
,
// 选中时间
check_time
:
0
,
});
// 开始定时任务
openInterval
(
res
.
data
.
hash
,
data
.
content
,
name
);
}
else
{
console
.
log
(
'报错了'
);
console
.
log
(
res
);
status
.
value
=
true
;
}
}
catch
(
e
)
{
status
.
value
=
true
;
console
.
log
(
e
);
}
};
onBeforeUnmount
(()
=>
{
closeInterval
();
});
return
{
CurrentVoice
,
SubmitConvertTask
,
};
}
src/pages/AILiveStreaming/DiscourseManagement/index.vue
View file @
581b5739
...
@@ -20,7 +20,12 @@ import CustomAudio from '@/components/Admin/audio.vue';
...
@@ -20,7 +20,12 @@ import CustomAudio from '@/components/Admin/audio.vue';
import
AdminPublicPageVue
from
'@/components/Admin/AdminPublicPage.vue'
;
import
AdminPublicPageVue
from
'@/components/Admin/AdminPublicPage.vue'
;
import
{
onBeforeMount
,
reactive
,
ref
}
from
'vue'
;
import
{
onBeforeMount
,
reactive
,
ref
}
from
'vue'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
FilterConfigFill
,
ResetForm
}
from
'@/constants/admin_form'
;
import
{
FilterConfigFill
,
ResetForm
,
DiscourseManagementDelete
,
language_list
,
}
from
'@/constants/admin_form'
;
import
{
discourse_management_edit
}
from
'@/constants/token'
;
import
{
discourse_management_edit
}
from
'@/constants/token'
;
import
{
import
{
DiscourseManagementConfig
,
DiscourseManagementConfig
,
...
@@ -92,6 +97,7 @@ const onFilter = async (params: any) => {
...
@@ -92,6 +97,7 @@ const onFilter = async (params: any) => {
console
.
log
(
e
);
console
.
log
(
e
);
}
}
};
};
// 表单配置项
// 表单配置项
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
title
:
'话术列表'
,
title
:
'话术列表'
,
...
@@ -112,6 +118,8 @@ const ManagementForm = reactive({
...
@@ -112,6 +118,8 @@ const ManagementForm = reactive({
table_api
:
getTableList
,
table_api
:
getTableList
,
// 能否多选--默认为true
// 能否多选--默认为true
checkbox
:
true
,
checkbox
:
true
,
// 删除api
delete_api
:
DiscourseManagementDelete
,
// 编辑页面
// 编辑页面
edit_page
:
'/AILiveStreaming/DiscourseManagement/edit'
,
edit_page
:
'/AILiveStreaming/DiscourseManagement/edit'
,
// 编辑页面的key--存储行数据
// 编辑页面的key--存储行数据
...
@@ -131,6 +139,7 @@ const ManagementForm = reactive({
...
@@ -131,6 +139,7 @@ const ManagementForm = reactive({
{
{
title
:
'check_all'
,
title
:
'check_all'
,
colKey
:
'checkbox'
,
colKey
:
'checkbox'
,
width
:
'80px'
,
},
},
{
{
title
:
'ID'
,
title
:
'ID'
,
...
@@ -195,16 +204,7 @@ const ManagementForm = reactive({
...
@@ -195,16 +204,7 @@ const ManagementForm = reactive({
label
:
'语言'
,
label
:
'语言'
,
placeholder
:
'语言'
,
placeholder
:
'语言'
,
value
:
''
,
value
:
''
,
options
:
[
options
:
language_list
,
{
label
:
'中文'
,
value
:
'cn'
,
},
{
label
:
'英文'
,
value
:
'en'
,
},
],
},
},
],
],
});
});
...
...
src/pages/AILiveStreaming/DiscourseManagementCreate/index.vue
View file @
581b5739
...
@@ -4,17 +4,52 @@
...
@@ -4,17 +4,52 @@
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
PageEdit
from
'@/components/Admin/PageEdit.vue'
;
import
PageEdit
from
'@/components/Admin/PageEdit.vue'
;
import
{
reactive
}
from
'vue'
;
import
{
onMounted
,
reactive
}
from
'vue'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
voice_list
}
from
'@/constants/admin_form'
;
import
{
voice_list
,
admin_task_type
}
from
'@/constants/admin_form'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
ConvertVoice
from
'@/hooks/ConvertVoice'
;
const
{
CurrentVoice
,
SubmitConvertTask
}
=
ConvertVoice
();
import
{
AddNewPhrase
}
from
'@/utils/api/ai'
;
const
router
=
useRouter
();
const
router
=
useRouter
();
const
imgs
=
{
const
imgs
=
{
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
};
};
// 获取选中的语言hash
const
getHash
=
()
=>
{
let
list
=
ManagementForm
.
conversion
.
list
;
const
index
=
list
.
findIndex
((
item
:
any
)
=>
item
.
is_check
);
return
index
!==
-
1
?
list
[
index
].
hash
:
''
;
};
//自定义提交事件
const
SubmitCreateEvent
=
async
()
=>
{
// 先过滤出选中的hash
const
hash
=
getHash
();
if
(
!
hash
)
{
show_message
(
'必须选择一条语音'
);
return
;
}
try
{
const
res
:
any
=
await
AddNewPhrase
({
hash
:
hash
,
});
if
(
res
.
code
==
0
)
{
show_message
(
'添加成功'
,
'success'
);
router
.
replace
({
path
:
ManagementForm
.
back_url
,
});
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 新增组件--所有value为空
// 新增组件--所有value为空
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
page_name
:
admin_task_type
.
dialogues
,
// 话术管理
title
:
'话术管理'
,
title
:
'话术管理'
,
title_2
:
'新增'
,
title_2
:
'新增'
,
body_title
:
'新增'
,
body_title
:
'新增'
,
...
@@ -25,17 +60,43 @@ const ManagementForm = reactive({
...
@@ -25,17 +60,43 @@ const ManagementForm = reactive({
delete
:
false
,
delete
:
false
,
// 删除api
// 删除api
// delete_api: isDevContext() ? '' : '',
// delete_api: isDevContext() ? '' : '',
// 能否提交
submit
:
true
,
// 提交接口
// 提交接口
submit_api
:
isDevContext
()
?
''
:
''
,
submit_api
:
SubmitCreateEvent
,
//能否重置
//能否重置
reset
:
true
,
reset
:
true
,
// 是否转换为语音
// 是否转换为语音
-- 自定义方法
conversion
:
{
conversion
:
{
api
:
''
,
list
:
CurrentVoice
.
list
,
options
:
[],
// 测试list
value
:
''
,
// list: [
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae962223668',
// is_check: false,
// status: true,
// check_time: 0,
// },
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae9622236681',
// is_check: false,
// status: true,
// check_time: 0,
// },
// ],
method
:
SubmitConvertTask
,
},
},
// 播放音频
// 播放音频
play_audio
:
true
,
play_audio
:
true
,
...
@@ -51,12 +112,24 @@ const ManagementForm = reactive({
...
@@ -51,12 +112,24 @@ const ManagementForm = reactive({
value
:
''
,
value
:
''
,
// 是否禁用
// 是否禁用
disabled
:
false
,
disabled
:
false
,
rules
:
[
{
type
:
'required'
,
message
:
'标题必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'产品'
,
label
:
'产品'
,
name
:
'product'
,
name
:
'product'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'产品必填'
,
},
],
},
},
],
],
},
},
...
@@ -82,6 +155,12 @@ const ManagementForm = reactive({
...
@@ -82,6 +155,12 @@ const ManagementForm = reactive({
value
:
'en'
,
value
:
'en'
,
},
},
],
],
rules
:
[
{
type
:
'required'
,
message
:
'语言必选'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -91,14 +170,25 @@ const ManagementForm = reactive({
...
@@ -91,14 +170,25 @@ const ManagementForm = reactive({
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
options
:
voice_list
,
options
:
voice_list
,
rules
:
[
{
type
:
'required'
,
message
:
'语音必选'
,
},
],
},
},
{
{
type
:
'textarea'
,
type
:
'textarea'
,
label
:
'语音内容'
,
label
:
'语音内容'
,
name
:
'
product_1
'
,
name
:
'
content
'
,
placeholder
:
'请输入语音内容'
,
placeholder
:
'请输入语音内容'
,
value
:
''
,
value
:
''
,
maxlength
:
1000
,
rules
:
[
{
type
:
'required'
,
message
:
'语音内容必填'
,
},
],
},
},
],
],
},
},
...
...
src/pages/AILiveStreaming/DiscourseManagementEdit/index.vue
View file @
581b5739
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
PageEdit
from
'@/components/Admin/PageEdit.vue'
;
import
PageEdit
from
'@/components/Admin/PageEdit.vue'
;
import
{
onBeforeMount
,
reactive
}
from
'vue'
;
import
{
onBeforeMount
,
reactive
,
ref
}
from
'vue'
;
import
{
discourse_management_edit
}
from
'@/constants/token'
;
import
{
discourse_management_edit
}
from
'@/constants/token'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
...
@@ -13,30 +13,108 @@ import {
...
@@ -13,30 +13,108 @@ import {
getEditLocalData
,
getEditLocalData
,
EditFillData
,
EditFillData
,
voice_list
,
voice_list
,
DiscourseManagementDelete
,
admin_task_type
,
}
from
'@/constants/admin_form'
;
}
from
'@/constants/admin_form'
;
import
{
EditVioce
}
from
'@/utils/api/ai'
;
import
ConvertVoice
from
'@/hooks/ConvertVoice'
;
const
{
CurrentVoice
,
SubmitConvertTask
}
=
ConvertVoice
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
old_hash
=
ref
(
''
);
const
cur_id
=
ref
();
const
imgs
=
{
const
imgs
=
{
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
};
};
// 获取选中的语言hash
const
getHash
=
()
=>
{
let
list
=
ManagementForm
.
conversion
.
list
;
const
index
=
list
.
findIndex
((
item
:
any
)
=>
item
.
is_check
);
return
index
!==
-
1
?
list
[
index
].
hash
:
''
;
};
//自定义提交事件
const
SubmitCreateEvent
=
async
()
=>
{
// 先过滤出选中的hash
const
hash
=
getHash
();
if
(
!
hash
||
!
old_hash
.
value
)
{
show_message
(
'必须选择一条语音'
);
return
;
}
try
{
const
res
:
any
=
await
EditVioce
({
hash
:
hash
,
old_hash
:
old_hash
.
value
,
});
if
(
res
.
code
==
0
)
{
show_message
(
'修改成功'
,
'success'
);
router
.
replace
({
path
:
ManagementForm
.
back_url
,
});
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 获取id
const
getRowid
=
()
=>
{
return
cur_id
.
value
+
''
;
};
// 编辑页面组件
// 编辑页面组件
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
page_name
:
admin_task_type
.
dialogues
,
// 话术管理
title
:
'话术管理'
,
title
:
'话术管理'
,
title_2
:
'编辑'
,
title_2
:
'编辑'
,
body_title
:
'编辑'
,
body_title
:
'编辑'
,
// 是否显示返回列表页
// 是否显示返回列表页
back
:
true
,
back
:
true
,
back_url
:
'/AILiveStreaming/DiscourseManagement'
,
back_url
:
'/AILiveStreaming/DiscourseManagement'
,
// 能否删除,
delete
:
true
,
// 删除api
// 删除api
delete_api
:
isDevContext
()
?
''
:
''
,
delete_api
:
DiscourseManagementDelete
,
// 能否提交
// 删除前是否确认
submit
:
true
,
delete_confirm
:
true
,
submit_api
:
isDevContext
()
?
''
:
''
,
// 提交方法
submit_api
:
SubmitCreateEvent
,
// 获取当前id
get_id
:
getRowid
,
//能否重置
//能否重置
reset
:
true
,
reset
:
true
,
// 是否转换为语音
// 是否转换为语音
conversion
:
true
,
// 是否转换为语音 -- 自定义方法
conversion
:
{
list
:
CurrentVoice
.
list
,
// 测试list
// list: [
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae962223668',
// is_check: false,
// status: true,
// check_time: 0,
// },
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae9622236681',
// is_check: false,
// status: true,
// check_time: 0,
// },
// ],
method
:
SubmitConvertTask
,
},
// 播放音频
// 播放音频
audio
:
{
audio
:
{
url
:
[],
url
:
[],
...
@@ -56,18 +134,31 @@ const ManagementForm = reactive({
...
@@ -56,18 +134,31 @@ const ManagementForm = reactive({
placeholder
:
''
,
placeholder
:
''
,
// 是否禁用
// 是否禁用
disabled
:
true
,
disabled
:
true
,
rules
:
[],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'标题'
,
label
:
'标题'
,
name
:
'title_1'
,
name
:
'title'
,
value
:
'奥克斯小风扇话术'
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'标题必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'产品'
,
label
:
'产品'
,
name
:
'product_1'
,
name
:
'product'
,
value
:
'电风扇'
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'产品必填'
,
},
],
},
},
],
],
},
},
...
@@ -93,6 +184,12 @@ const ManagementForm = reactive({
...
@@ -93,6 +184,12 @@ const ManagementForm = reactive({
value
:
'en'
,
value
:
'en'
,
},
},
],
],
rules
:
[
{
type
:
'required'
,
message
:
'语言必选'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -102,13 +199,25 @@ const ManagementForm = reactive({
...
@@ -102,13 +199,25 @@ const ManagementForm = reactive({
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
options
:
voice_list
,
options
:
voice_list
,
rules
:
[
{
type
:
'required'
,
message
:
'语音必选'
,
},
],
},
},
{
{
type
:
'textarea'
,
type
:
'textarea'
,
label
:
'语音内容'
,
label
:
'语音内容'
,
name
:
'
product_1
'
,
name
:
'
content
'
,
placeholder
:
'请输入语音内容'
,
placeholder
:
'请输入语音内容'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'语音内容必填'
,
},
],
},
},
],
],
},
},
...
@@ -120,8 +229,20 @@ onBeforeMount(() => {
...
@@ -120,8 +229,20 @@ onBeforeMount(() => {
discourse_management_edit
,
discourse_management_edit
,
ManagementForm
.
back_url
ManagementForm
.
back_url
);
);
//
填充数据
//
公共数据填充
EditFillData
(
ManagementForm
.
form_options
,
row
);
EditFillData
(
ManagementForm
.
form_options
,
row
);
// 填充原有的语音列表
ManagementForm
.
conversion
.
list
.
push
({
hash
:
row
.
hash
,
status
:
true
,
audio
:
row
.
audio
,
content
:
row
.
content
,
is_check
:
false
,
check_time
:
0
,
});
// 获取old_hash
old_hash
.
value
=
row
.
hash
;
cur_id
.
value
=
row
.
id
;
});
});
</
script
>
</
script
>
...
...
src/pages/AILiveStreaming/InteractiveSetting/index.vue
View file @
581b5739
...
@@ -4,18 +4,63 @@
...
@@ -4,18 +4,63 @@
v-model:list=
"ManagementForm.table_list"
v-model:list=
"ManagementForm.table_list"
@
reset=
"ResetFilter"
@
reset=
"ResetFilter"
>
>
<template
#
t
itle
>
<template
#
t
ype=
"
{ row }"
>
<
div>
111
</div
>
<
span>
{{
interaction_type
[
row
.
type
]
}}
</span
>
</
template
>
</
template
>
</AdminPublicPageVue>
</AdminPublicPageVue>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
AdminPublicPageVue
from
'@/components/Admin/AdminPublicPage.vue'
;
import
AdminPublicPageVue
from
'@/components/Admin/AdminPublicPage.vue'
;
import
{
reactive
}
from
'vue'
;
import
{
reactive
,
onBeforeMount
,
ref
}
from
'vue'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
ResetForm
}
from
'@/constants/admin_form'
;
import
{
ResetForm
,
FilterConfigFill
,
language_list
,
interaction_type
,
}
from
'@/constants/admin_form'
;
import
{
interactive_setting_edit
}
from
'@/constants/token'
;
import
{
interactive_setting_edit
}
from
'@/constants/token'
;
import
{
InteractionFilterConfig
,
InteractionTableList
,
InteractionFilter
,
}
from
'@/utils/api/ai'
;
const
pageNum
=
ref
(
1
);
const
pageSize
=
ref
(
10
);
// 获取表格数据
const
getTableList
=
async
()
=>
{
try
{
const
res
:
any
=
await
InteractionTableList
({
page
:
pageNum
.
value
,
limit
:
pageSize
.
value
,
});
const
list
=
res
.
data
.
data
;
return
{
list
:
list
,
total
:
res
.
data
.
total
,
};
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 开始筛选
const
onFilter
=
async
(
params
:
any
)
=>
{
try
{
const
res
:
any
=
await
InteractionFilter
({
page
:
pageNum
.
value
,
limit
:
pageSize
.
value
,
...
params
,
});
return
{
list
:
res
.
data
.
data
,
total
:
res
.
data
.
total
,
};
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 表单配置项
// 表单配置项
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
title
:
'互动设置'
,
title
:
'互动设置'
,
...
@@ -25,7 +70,7 @@ const ManagementForm = reactive({
...
@@ -25,7 +70,7 @@ const ManagementForm = reactive({
// 能否筛选
// 能否筛选
filter
:
true
,
filter
:
true
,
// 筛选接口
// 筛选接口
filter_api
:
isDevContext
()
?
''
:
''
,
filter_api
:
onFilter
,
// 能否新增
// 能否新增
add
:
true
,
add
:
true
,
// 表格key--用来缓存表格分页
// 表格key--用来缓存表格分页
...
@@ -33,9 +78,7 @@ const ManagementForm = reactive({
...
@@ -33,9 +78,7 @@ const ManagementForm = reactive({
// 表格数据
// 表格数据
table_list
:
[],
table_list
:
[],
// 表格接口
// 表格接口
table_api
:
isDevContext
()
?
''
:
''
,
table_api
:
getTableList
,
// api类型
table_api_type
:
'get'
,
// 能否多选--默认为true
// 能否多选--默认为true
checkbox
:
true
,
checkbox
:
true
,
// 编辑页面
// 编辑页面
...
@@ -86,52 +129,36 @@ const ManagementForm = reactive({
...
@@ -86,52 +129,36 @@ const ManagementForm = reactive({
filter_option
:
[
filter_option
:
[
{
{
type
:
'select'
,
type
:
'select'
,
name
:
'
select_
title'
,
name
:
'title'
,
label
:
'标题'
,
label
:
'标题'
,
placeholder
:
'请选择标题'
,
placeholder
:
'请选择标题'
,
value
:
''
,
value
:
''
,
options
:
[
// 能否输入
{
filterable
:
true
,
label
:
'你好'
,
options
:
[],
value
:
'你好'
,
},
{
label
:
'你好2'
,
value
:
'你好2'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
name
:
'
select_product
'
,
name
:
'
language
'
,
label
:
'
产品
'
,
label
:
'
语言
'
,
placeholder
:
'
产品
'
,
placeholder
:
'
请选择语言
'
,
value
:
''
,
value
:
''
,
options
:
[
options
:
language_list
,
{
label
:
'你好'
,
value
:
'你好'
,
},
{
label
:
'你好2'
,
value
:
'你好2'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
name
:
'
select_languag
e'
,
name
:
'
typ
e'
,
label
:
'
语言
'
,
label
:
'
类型
'
,
placeholder
:
'
语言
'
,
placeholder
:
'
请选择类型
'
,
value
:
''
,
value
:
''
,
options
:
[
options
:
[
{
{
label
:
'
你好
'
,
label
:
'
直播互动
'
,
value
:
'
你好
'
,
value
:
'
0
'
,
},
},
{
{
label
:
'
你好2
'
,
label
:
'
自动回复
'
,
value
:
'
你好2
'
,
value
:
'
1
'
,
},
},
],
],
},
},
...
@@ -143,6 +170,21 @@ const ManagementForm = reactive({
...
@@ -143,6 +170,21 @@ const ManagementForm = reactive({
const
ResetFilter
=
()
=>
{
const
ResetFilter
=
()
=>
{
ResetForm
(
ManagementForm
.
filter_option
);
ResetForm
(
ManagementForm
.
filter_option
);
};
};
// 获取筛选列表配置
const
getFilterList
=
async
()
=>
{
try
{
const
res
:
any
=
await
InteractionFilterConfig
();
if
(
res
.
data
)
{
FilterConfigFill
(
res
.
data
,
ManagementForm
.
filter_option
);
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
onBeforeMount
(()
=>
{
getFilterList
();
});
</
script
>
</
script
>
<
style
lang=
"less"
></
style
>
<
style
lang=
"less"
></
style
>
src/pages/AILiveStreaming/InteractiveSettingCreate/index.vue
View file @
581b5739
...
@@ -8,12 +8,26 @@ import { reactive } from 'vue';
...
@@ -8,12 +8,26 @@ import { reactive } from 'vue';
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
admin_task_type
}
from
'@/constants/admin_form'
;
const
router
=
useRouter
();
const
router
=
useRouter
();
const
imgs
=
{
const
imgs
=
{
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
};
};
// 修改组件显示状态
const
ChangeComponentsShow
=
(
value
:
string
)
=>
{
ManagementForm
.
form_options
.
forEach
((
item
:
any
)
=>
{
if
(
item
.
name
===
value
)
{
item
.
is_hidden
=
false
;
}
if
(
item
.
name
!==
value
&&
item
.
is_hidden
===
false
)
{
item
.
is_hidden
=
true
;
}
});
};
// 新增组件--所有value为空
// 新增组件--所有value为空
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
page_name
:
admin_task_type
.
interaction
,
title
:
'互动设置'
,
title
:
'互动设置'
,
title_2
:
'新增'
,
title_2
:
'新增'
,
body_title
:
'新增'
,
body_title
:
'新增'
,
...
@@ -23,11 +37,8 @@ const ManagementForm = reactive({
...
@@ -23,11 +37,8 @@ const ManagementForm = reactive({
// 能否删除,
// 能否删除,
delete
:
false
,
delete
:
false
,
// 删除api
// 删除api
// delete_api: isDevContext() ? '' : '',
delete_api
:
''
,
// 能否提交
submit_api
:
'1'
,
submit
:
true
,
// 提交接口
submit_api
:
isDevContext
()
?
''
:
''
,
//能否重置
//能否重置
reset
:
true
,
reset
:
true
,
// 是否转换为语音
// 是否转换为语音
...
@@ -40,13 +51,23 @@ const ManagementForm = reactive({
...
@@ -40,13 +51,23 @@ const ManagementForm = reactive({
title
:
''
,
title
:
''
,
lists
:
[
lists
:
[
{
{
type
:
'
tex
t'
,
type
:
'
selec
t'
,
label
:
'类型'
,
label
:
'类型'
,
name
:
'title_1'
,
name
:
'select_type'
,
value
:
''
,
placeholder
:
'请选择类型'
,
placeholder
:
'请输入类型'
,
value
:
'auto'
,
// 是否禁用
align
:
'left'
,
disabled
:
false
,
watch
:
ChangeComponentsShow
,
options
:
[
{
label
:
'自动回复设置'
,
value
:
'auto'
,
},
{
label
:
'串场互动话术设置'
,
value
:
'crosstown'
,
},
],
},
},
],
],
},
},
...
@@ -57,7 +78,7 @@ const ManagementForm = reactive({
...
@@ -57,7 +78,7 @@ const ManagementForm = reactive({
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'语言'
,
label
:
'语言'
,
name
:
'language
_1
'
,
name
:
'language'
,
placeholder
:
'请选择语言'
,
placeholder
:
'请选择语言'
,
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
...
@@ -93,24 +114,49 @@ const ManagementForm = reactive({
...
@@ -93,24 +114,49 @@ const ManagementForm = reactive({
},
},
],
],
},
},
// 串场互动
{
{
icon
:
'crossTalk'
,
icon
:
'message'
,
title
:
'自动回复设置'
,
is_hidden
:
false
,
name
:
'auto'
,
lists
:
[
{
type
:
'text'
,
label
:
'触发关键词'
,
name
:
'language_20'
,
placeholder
:
'请输入'
,
value
:
''
,
align
:
'left'
,
},
{
type
:
'textarea'
,
label
:
'回复内容'
,
name
:
'product_30'
,
placeholder
:
'请输入语音内容'
,
value
:
''
,
},
],
},
{
icon
:
'discourseBind'
,
title
:
'串场互动话术设置'
,
title
:
'串场互动话术设置'
,
is_hidden
:
true
,
name
:
'crosstown'
,
lists
:
[
lists
:
[
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'标题'
,
label
:
'标题'
,
name
:
'title_1'
,
name
:
'language_20'
,
placeholder
:
'请输入'
,
value
:
''
,
value
:
''
,
placeholder
:
'请输入标题
'
,
align
:
'left
'
,
},
},
{
{
type
:
'textarea'
,
type
:
'textarea'
,
label
:
'话术内容'
,
label
:
'话术内容'
,
name
:
'title_2'
,
name
:
'product_30'
,
value
:
''
,
placeholder
:
'请输入话术内容'
,
placeholder
:
'请输入话术内容'
,
value
:
''
,
},
},
],
],
},
},
...
...
src/pages/AILiveStreaming/InteractiveSettingEdit/index.vue
View file @
581b5739
...
@@ -9,7 +9,14 @@ import { interactive_setting_edit } from '@/constants/token';
...
@@ -9,7 +9,14 @@ import { interactive_setting_edit } from '@/constants/token';
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
getEditLocalData
,
EditFillData
}
from
'@/constants/admin_form'
;
import
{
getEditLocalData
,
EditFillData
,
admin_task_type
,
voice_list
,
}
from
'@/constants/admin_form'
;
import
ConvertVoice
from
'@/hooks/ConvertVoice'
;
const
{
CurrentVoice
,
SubmitConvertTask
}
=
ConvertVoice
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
imgs
=
{
const
imgs
=
{
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
...
@@ -27,25 +34,52 @@ const ChangeComponentsShow = (value: string) => {
...
@@ -27,25 +34,52 @@ const ChangeComponentsShow = (value: string) => {
};
};
// 编辑页面组件
// 编辑页面组件
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
page_name
:
admin_task_type
.
interaction
,
title
:
'互动设置'
,
title
:
'互动设置'
,
title_2
:
'编辑'
,
title_2
:
'编辑'
,
body_title
:
'编辑'
,
body_title
:
'编辑'
,
// 是否显示返回列表页
// 是否显示返回列表页
back
:
true
,
back
:
true
,
back_url
:
'/AILiveStreaming/InteractiveSetting'
,
back_url
:
'/AILiveStreaming/InteractiveSetting'
,
// 能否删除,
delete
:
true
,
// 删除api
// 删除api
delete_api
:
isDevContext
()
?
''
:
''
,
delete_api
:
'1'
,
// 能否提交
submit_api
:
'1'
,
submit
:
true
,
submit_api
:
isDevContext
()
?
''
:
''
,
//能否重置
//能否重置
reset
:
true
,
reset
:
true
,
// 是否转换为语音
// 是否转换为语音 -- 自定义方法
conversion
:
false
,
conversion
:
{
// 播放音频
list
:
CurrentVoice
.
list
,
play_audio
:
false
,
// 测试list
// list: [
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae962223668',
// is_check: false,
// status: true,
// check_time: 0,
// },
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae9622236681',
// is_check: false,
// status: true,
// check_time: 0,
// },
// ],
method
:
SubmitConvertTask
,
},
form_options
:
[
form_options
:
[
{
{
icon
:
''
,
icon
:
''
,
...
@@ -54,7 +88,7 @@ const ManagementForm = reactive({
...
@@ -54,7 +88,7 @@ const ManagementForm = reactive({
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'类型'
,
label
:
'类型'
,
name
:
'
language_1
'
,
name
:
'
select_type
'
,
placeholder
:
'请选择类型'
,
placeholder
:
'请选择类型'
,
value
:
'auto'
,
value
:
'auto'
,
align
:
'left'
,
align
:
'left'
,
...
@@ -79,7 +113,7 @@ const ManagementForm = reactive({
...
@@ -79,7 +113,7 @@ const ManagementForm = reactive({
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'语言'
,
label
:
'语言'
,
name
:
'language
_1
'
,
name
:
'language'
,
placeholder
:
'请选择语言'
,
placeholder
:
'请选择语言'
,
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
...
@@ -102,16 +136,7 @@ const ManagementForm = reactive({
...
@@ -102,16 +136,7 @@ const ManagementForm = reactive({
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
audio
:
true
,
audio
:
true
,
options
:
[
options
:
voice_list
,
{
label
:
'小微 (直播间专属)'
,
value
:
'123'
,
},
{
label
:
'小爱 (直播间专属)'
,
value
:
'12345'
,
},
],
},
},
],
],
},
},
...
...
src/utils/api/ai.ts
View file @
581b5739
...
@@ -4,9 +4,12 @@ import { getUserCookie } from './userApi';
...
@@ -4,9 +4,12 @@ import { getUserCookie } from './userApi';
* ai直播模块接口
* ai直播模块接口
*/
*/
/**
* 话术管理模块
*/
// 话术管理配置信息
// 话术管理配置信息
export
const
DiscourseManagementConfig
=
()
=>
{
export
const
DiscourseManagementConfig
=
()
=>
{
return
request
.
get
(
'/api/voices/
get-user
-config'
,
{
return
request
.
get
(
'/api/voices/
voice
-config'
,
{
headers
:
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
},
...
@@ -15,7 +18,7 @@ export const DiscourseManagementConfig = () => {
...
@@ -15,7 +18,7 @@ export const DiscourseManagementConfig = () => {
// 话术管理表格
// 话术管理表格
export
const
DiscourseManagementList
=
(
data
:
any
)
=>
{
export
const
DiscourseManagementList
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/
get-
voice-live'
,
{
return
request
.
get
(
'/api/voices/voice-live'
,
{
params
:
data
,
params
:
data
,
headers
:
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
authorization
:
`Bearer
${
getUserCookie
()}
`
,
...
@@ -25,10 +28,116 @@ export const DiscourseManagementList = (data: any) => {
...
@@ -25,10 +28,116 @@ export const DiscourseManagementList = (data: any) => {
// 话术管理筛选
// 话术管理筛选
export
const
DiscourseManagementFilter
=
(
data
:
any
)
=>
{
export
const
DiscourseManagementFilter
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/
get-config
-filter'
,
{
return
request
.
get
(
'/api/voices/
voice
-filter'
,
{
params
:
data
,
params
:
data
,
headers
:
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
},
});
});
};
};
// 话术管理提交语音转换任务
export
const
DiscourseManagementConvertTask
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/add-task'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 语音转换任务返回值
export
const
ConvertTaskResponse
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/query-voice'
,
{
params
:
data
,
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 新增话术
export
const
AddNewPhrase
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/save-voice'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 编辑话术
export
const
EditVioce
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/update-voice'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 删除话术
export
const
DeleteVioce
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/delete-voice'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
/**
* 话术管理 end
*/
/**
* 互动设置模块 Interaction
*/
// 获取筛选配置
export
const
InteractionFilterConfig
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/interact-config'
,
{
params
:
data
,
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 筛选
export
const
InteractionFilter
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/interact-filter'
,
{
params
:
data
,
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 获取表格数据
export
const
InteractionTableList
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/voice-interact'
,
{
params
:
data
,
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 提交生成语音任务
export
const
SubmitTaskInteract
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/add-task-interact'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
// 轮询获取语音任务返回值
export
const
QueryInteractResponse
=
(
data
:
any
)
=>
{
return
request
.
get
(
'/api/voices/query-interact'
,
{
params
:
data
,
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
/**
* 互动设置 end
*/
src/utils/request.ts
View file @
581b5739
...
@@ -29,7 +29,7 @@ instance.defaults.timeout = 60000;
...
@@ -29,7 +29,7 @@ instance.defaults.timeout = 60000;
instance
.
interceptors
.
response
.
use
(
instance
.
interceptors
.
response
.
use
(
(
response
)
=>
{
(
response
)
=>
{
const
{
data
}
=
response
;
const
{
data
}
=
response
;
if
(
data
.
code
===
0
||
data
.
code
==
201
)
{
if
(
data
.
code
===
0
||
data
.
code
==
201
||
data
.
code
==
1
)
{
return
data
;
return
data
;
}
else
{
}
else
{
show_message
(
data
.
msg
||
'请求错误'
,
'error'
);
show_message
(
data
.
msg
||
'请求错误'
,
'error'
);
...
...
src/utils/tool.ts
View file @
581b5739
...
@@ -237,3 +237,11 @@ export const isDevContext = () => {
...
@@ -237,3 +237,11 @@ export const isDevContext = () => {
const
is_dev
=
import
.
meta
.
env
.
DEV
;
const
is_dev
=
import
.
meta
.
env
.
DEV
;
return
is_dev
?
true
:
false
;
return
is_dev
?
true
:
false
;
};
};
// 判断数据类型
export
const
DataType
=
(
key
:
'array'
|
'string'
,
value
:
any
)
=>
{
const
toString
=
Object
.
prototype
.
toString
;
if
(
key
==
'array'
)
{
return
toString
.
call
(
value
)
===
'[object Array]'
;
}
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment