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
43de7cb4
Commit
43de7cb4
authored
May 22, 2023
by
haojie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
514c2ba3
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
245 additions
and
83 deletions
+245
-83
src/components/Admin/PageEdit.vue
+12
-5
src/components/Admin/select.vue
+3
-0
src/pages/AILiveStreaming/LiveStreamCreate/index.vue
+37
-1
src/pages/AILiveStreaming/LiveStreamDetail/index.vue
+55
-33
src/pages/AILiveStreaming/LiveStreamEdit/index.vue
+37
-1
src/pages/AILiveStreaming/LiveStreamReply/index.vue
+92
-43
src/utils/api/ai.ts
+9
-0
No files found.
src/components/Admin/PageEdit.vue
View file @
43de7cb4
...
@@ -90,6 +90,7 @@
...
@@ -90,6 +90,7 @@
:item=
"
{}"
:item=
"
{}"
:align="it.align"
:align="it.align"
:audio="it.audio"
:audio="it.audio"
:disabled="it.disabled ?? false"
:audio_list="audio_list"
:audio_list="audio_list"
:is_watch="it.watch ? it.watch : false"
:is_watch="it.watch ? it.watch : false"
width="100%"
width="100%"
...
@@ -228,17 +229,23 @@ const backTable = () => {
...
@@ -228,17 +229,23 @@ const backTable = () => {
};
};
// 发起请求
// 发起请求
const
onSend
=
()
=>
{
const
onSend
=
async
()
=>
{
//
//
const
{
is_send
}
=
props
.
form
;
const
{
is_send
,
form_options
}
=
props
.
form
;
if
(
is_send
&&
is_send
.
api
)
{
if
(
is_send
&&
is_send
.
api
&&
!
is_send
.
disabled
)
{
//
// 获取表单数据
const
params
=
getFormParams
(
form_options
);
if
(
!
params
)
{
return
;
}
loading
.
value
=
true
;
await
is_send
.
api
(
params
);
loading
.
value
=
false
;
}
}
};
};
// 下拉框事件
// 下拉框事件
const
SelectChange
=
(
value
:
string
,
fun
:
any
)
=>
{
const
SelectChange
=
(
value
:
string
,
fun
:
any
)
=>
{
console
.
log
(
value
);
fun
(
value
);
fun
(
value
);
};
};
...
...
src/components/Admin/select.vue
View file @
43de7cb4
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
:filterable=
"filterable"
:filterable=
"filterable"
:multiple=
"multiple"
:multiple=
"multiple"
:disabled=
"disabled"
:popupProps=
"
{
:popupProps=
"
{
overlayClassName: [className, 'admin-select-popup'],
overlayClassName: [className, 'admin-select-popup'],
}"
}"
...
@@ -51,6 +52,7 @@ const props = withDefaults(
...
@@ -51,6 +52,7 @@ const props = withDefaults(
audio_list
?:
string
[];
audio_list
?:
string
[];
name
?:
string
;
name
?:
string
;
multiple
?:
boolean
;
multiple
?:
boolean
;
disabled
?:
boolean
;
}
>
(),
}
>
(),
{
{
width
:
'357px'
,
width
:
'357px'
,
...
@@ -60,6 +62,7 @@ const props = withDefaults(
...
@@ -60,6 +62,7 @@ const props = withDefaults(
filterable
:
false
,
filterable
:
false
,
audio_list
:
()
=>
[],
audio_list
:
()
=>
[],
multiple
:
false
,
multiple
:
false
,
disabled
:
false
,
}
}
);
);
const
emit
=
defineEmits
([
'update:modelValue'
,
'change'
,
'ValueChange'
]);
const
emit
=
defineEmits
([
'update:modelValue'
,
'change'
,
'ValueChange'
]);
...
...
src/pages/AILiveStreaming/LiveStreamCreate/index.vue
View file @
43de7cb4
...
@@ -66,6 +66,12 @@ const ManagementForm = reactive({
...
@@ -66,6 +66,12 @@ const ManagementForm = reactive({
name
:
'live_title'
,
name
:
'live_title'
,
value
:
''
,
value
:
''
,
placeholder
:
'请输入直播间标题'
,
placeholder
:
'请输入直播间标题'
,
rules
:
[
{
type
:
'required'
,
message
:
'直播间标题必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
...
@@ -73,6 +79,12 @@ const ManagementForm = reactive({
...
@@ -73,6 +79,12 @@ const ManagementForm = reactive({
name
:
'live_link'
,
name
:
'live_link'
,
value
:
''
,
value
:
''
,
placeholder
:
'请输入直播间链接'
,
placeholder
:
'请输入直播间链接'
,
rules
:
[
{
type
:
'required'
,
message
:
'直播间链接必填'
,
},
],
},
},
],
],
},
},
...
@@ -84,11 +96,17 @@ const ManagementForm = reactive({
...
@@ -84,11 +96,17 @@ const ManagementForm = reactive({
type
:
'select'
,
type
:
'select'
,
label
:
'直播话术'
,
label
:
'直播话术'
,
name
:
'live_voice'
,
name
:
'live_voice'
,
placeholder
:
'请选择
语言
'
,
placeholder
:
'请选择
直播话术
'
,
value
:
[],
value
:
[],
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'直播话术必选'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -99,6 +117,12 @@ const ManagementForm = reactive({
...
@@ -99,6 +117,12 @@ const ManagementForm = reactive({
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'自动回复话术必填'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -109,12 +133,24 @@ const ManagementForm = reactive({
...
@@ -109,12 +133,24 @@ const ManagementForm = reactive({
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'串场互动话术必填'
,
},
],
},
},
{
{
type
:
'number'
,
type
:
'number'
,
name
:
'interaction_interval'
,
name
:
'interaction_interval'
,
label
:
'串场互动触发时间间隔'
,
label
:
'串场互动触发时间间隔'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'间隔时间必填'
,
},
],
},
},
],
],
},
},
...
...
src/pages/AILiveStreaming/LiveStreamDetail/index.vue
View file @
43de7cb4
...
@@ -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
{
live_stream_detail
}
from
'@/constants/token'
;
import
{
live_stream_detail
}
from
'@/constants/token'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
...
@@ -18,7 +18,9 @@ const router = useRouter();
...
@@ -18,7 +18,9 @@ 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
cur_id
=
ref
(
''
);
const
cur_hash
=
ref
(
''
);
// 查看页面
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
title
:
'直播管理'
,
title
:
'直播管理'
,
title_2
:
'查看'
,
title_2
:
'查看'
,
...
@@ -47,16 +49,29 @@ const ManagementForm = reactive({
...
@@ -47,16 +49,29 @@ const ManagementForm = reactive({
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'直播间标题'
,
label
:
'直播间标题'
,
name
:
'
title_1
'
,
name
:
'
live_title
'
,
value
:
''
,
value
:
''
,
disabled
:
true
,
disabled
:
true
,
placeholder
:
''
,
placeholder
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'标题必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
label
:
'直播间
连
接'
,
label
:
'直播间
链
接'
,
name
:
'
title_12
'
,
name
:
'
live_link
'
,
value
:
''
,
value
:
''
,
disabled
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'链接必填'
,
},
],
},
},
],
],
},
},
...
@@ -67,62 +82,66 @@ const ManagementForm = reactive({
...
@@ -67,62 +82,66 @@ const ManagementForm = reactive({
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'直播话术'
,
label
:
'直播话术'
,
name
:
'l
anguage_1
'
,
name
:
'l
ive_voice
'
,
placeholder
:
'
请选择语言
'
,
placeholder
:
''
,
value
:
''
,
value
:
[]
,
align
:
'left'
,
align
:
'left'
,
options
:
[
options
:
[],
{
multiple
:
true
,
label
:
'话术1'
,
disabled
:
true
,
value
:
'cn'
,
rules
:
[
},
{
{
label
:
'话术2
'
,
type
:
'required
'
,
value
:
'en
'
,
message
:
'直播话术必选
'
,
},
},
],
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'自动回复话术'
,
label
:
'自动回复话术'
,
name
:
'
voice
'
,
name
:
'
live_auto
'
,
placeholder
:
'请选择自动回复话术'
,
placeholder
:
'请选择自动回复话术'
,
value
:
''
,
value
:
[]
,
align
:
'left'
,
align
:
'left'
,
options
:
[
multiple
:
true
,
{
disabled
:
true
,
label
:
'自动回复话术1'
,
options
:
[],
value
:
'123'
,
rules
:
[
},
{
{
label
:
'自动回复话术2
'
,
type
:
'required
'
,
value
:
'12345
'
,
message
:
'自动回复话术必选
'
,
},
},
],
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'串场互动话术'
,
label
:
'串场互动话术'
,
name
:
'
voice
'
,
name
:
'
live_interaction
'
,
placeholder
:
'请选择串场互动话术'
,
placeholder
:
'请选择串场互动话术'
,
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
options
:
[
options
:
[],
{
multiple
:
true
,
label
:
'串场互动话术1'
,
disabled
:
true
,
value
:
'123'
,
rules
:
[
},
{
{
label
:
'串场互动话术2
'
,
type
:
'required
'
,
value
:
'12345
'
,
message
:
'串场互动话术必选
'
,
},
},
],
],
},
},
{
{
type
:
'number'
,
type
:
'number'
,
name
:
'number'
,
name
:
'interaction_interval'
,
disabled
:
true
,
label
:
'串场互动触发时间间隔'
,
label
:
'串场互动触发时间间隔'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'间隔时间必填'
,
},
],
},
},
],
],
},
},
...
@@ -138,6 +157,9 @@ onBeforeMount(async () => {
...
@@ -138,6 +157,9 @@ onBeforeMount(async () => {
// 本地是否有缓存
// 本地是否有缓存
const
row
=
getEditLocalData
(
live_stream_detail
,
ManagementForm
.
back_url
);
const
row
=
getEditLocalData
(
live_stream_detail
,
ManagementForm
.
back_url
);
EditFillData
(
ManagementForm
.
form_options
,
row
);
EditFillData
(
ManagementForm
.
form_options
,
row
);
cur_id
.
value
=
row
.
id
;
cur_hash
.
value
=
row
.
hash
;
});
});
</
script
>
</
script
>
...
...
src/pages/AILiveStreaming/LiveStreamEdit/index.vue
View file @
43de7cb4
...
@@ -84,6 +84,12 @@ const ManagementForm = reactive({
...
@@ -84,6 +84,12 @@ const ManagementForm = reactive({
name
:
'live_title'
,
name
:
'live_title'
,
value
:
''
,
value
:
''
,
placeholder
:
'请输入直播间标题'
,
placeholder
:
'请输入直播间标题'
,
rules
:
[
{
type
:
'required'
,
message
:
'标题必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
...
@@ -91,6 +97,12 @@ const ManagementForm = reactive({
...
@@ -91,6 +97,12 @@ const ManagementForm = reactive({
name
:
'live_link'
,
name
:
'live_link'
,
value
:
''
,
value
:
''
,
placeholder
:
'请输入直播间链接'
,
placeholder
:
'请输入直播间链接'
,
rules
:
[
{
type
:
'required'
,
message
:
'链接必填'
,
},
],
},
},
],
],
},
},
...
@@ -102,11 +114,17 @@ const ManagementForm = reactive({
...
@@ -102,11 +114,17 @@ const ManagementForm = reactive({
type
:
'select'
,
type
:
'select'
,
label
:
'直播话术'
,
label
:
'直播话术'
,
name
:
'live_voice'
,
name
:
'live_voice'
,
placeholder
:
'请选择
语言
'
,
placeholder
:
'请选择
直播话术
'
,
value
:
[],
value
:
[],
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'直播话术必选'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -117,6 +135,12 @@ const ManagementForm = reactive({
...
@@ -117,6 +135,12 @@ const ManagementForm = reactive({
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'自动回复话术必选'
,
},
],
},
},
{
{
type
:
'select'
,
type
:
'select'
,
...
@@ -127,12 +151,24 @@ const ManagementForm = reactive({
...
@@ -127,12 +151,24 @@ const ManagementForm = reactive({
align
:
'left'
,
align
:
'left'
,
options
:
[],
options
:
[],
multiple
:
true
,
multiple
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'串场互动话术必选'
,
},
],
},
},
{
{
type
:
'number'
,
type
:
'number'
,
name
:
'interaction_interval'
,
name
:
'interaction_interval'
,
label
:
'串场互动触发时间间隔'
,
label
:
'串场互动触发时间间隔'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'间隔时间必填'
,
},
],
},
},
{
{
type
:
'text'
,
type
:
'text'
,
...
...
src/pages/AILiveStreaming/LiveStreamReply/index.vue
View file @
43de7cb4
<
template
>
<
template
>
<PageEdit
:form=
"ManagementForm"
></PageEdit>
<PageEdit
:form=
"ManagementForm"
:audio_list=
"audio_list"
@
ConfigChange=
"ConfigChange"
></PageEdit>
</
template
>
</
template
>
<
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
,
watch
,
ref
}
from
'vue'
;
import
{
live_stream_edit
}
from
'@/constants/token'
;
import
{
live_stream_reply
}
from
'@/constants/token'
;
import
{
getLocalData
,
isDevContext
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
language_list
,
voice_list
,
getEditLocalData
,
EditFillData
,
}
from
'@/constants/admin_form'
;
import
{
LiveStreamTaskManual
}
from
'@/utils/api/ai'
;
import
{
show_message
}
from
'@/utils/tdesign_tool'
;
const
router
=
useRouter
();
const
router
=
useRouter
();
const
imgs
=
{
// 当前试听语音
fill
:
new
URL
(
'../../../assets/svg/form/edit.svg'
,
import
.
meta
.
url
).
href
,
const
audio_list
=
ref
([]);
// 记录当前语音和语言
const
CurrentConfig
=
reactive
({
language
:
''
,
voice
:
''
,
});
watch
(
CurrentConfig
,
(
config
)
=>
{
if
(
config
.
language
&&
config
.
voice
)
{
// 修改试听语音
const
obj
=
voice_list
.
find
((
item
:
any
)
=>
item
.
value
==
config
.
voice
);
if
(
obj
)
{
audio_list
.
value
=
[
obj
.
audio
[
config
.
language
]];
}
}
});
const
ConfigChange
=
(
name
:
string
,
value
:
string
)
=>
{
CurrentConfig
[
name
]
=
value
;
};
// 发送接口
const
onSend
=
async
(
data
:
any
)
=>
{
try
{
//
const
res
:
any
=
await
LiveStreamTaskManual
(
data
);
if
(
res
.
code
==
0
)
{
show_message
(
'提交成功'
,
'success'
);
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
};
// 编辑页面组件
// 编辑页面组件
const
ManagementForm
=
reactive
({
const
ManagementForm
=
reactive
({
...
@@ -24,10 +63,12 @@ const ManagementForm = reactive({
...
@@ -24,10 +63,12 @@ const ManagementForm = reactive({
// 能否删除,
// 能否删除,
delete
:
false
,
delete
:
false
,
// 删除api
// 删除api
delete_api
:
isDevContext
()
?
''
:
''
,
delete_api
:
''
,
// 是否试听
audition
:
true
,
// 能否提交
// 能否提交
submit
:
false
,
submit
:
false
,
submit_api
:
isDevContext
()
?
''
:
''
,
submit_api
:
''
,
//能否重置
//能否重置
reset
:
false
,
reset
:
false
,
// 是否转换为语音
// 是否转换为语音
...
@@ -36,9 +77,12 @@ const ManagementForm = reactive({
...
@@ -36,9 +77,12 @@ const ManagementForm = reactive({
play_audio
:
false
,
play_audio
:
false
,
// 发送按钮
// 发送按钮
is_send
:
{
is_send
:
{
// 只有进行中才可以发送
disabled
:
true
,
disabled
:
true
,
label
:
'发送'
,
label
:
'发送'
,
api
:
isDevContext
()
?
''
:
''
,
api
:
onSend
,
// 是否自定义parmas,没有就从表单取
// params:''
},
},
form_options
:
[
form_options
:
[
{
{
...
@@ -48,18 +92,15 @@ const ManagementForm = reactive({
...
@@ -48,18 +92,15 @@ const ManagementForm = reactive({
{
{
type
:
'select'
,
type
:
'select'
,
label
:
'语言'
,
label
:
'语言'
,
name
:
'language
_1
'
,
name
:
'language'
,
placeholder
:
'请选择语言'
,
placeholder
:
'请选择语言'
,
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
options
:
[
options
:
language_list
,
{
rules
:
[
label
:
'中文'
,
value
:
'cn'
,
},
{
{
label
:
'英语
'
,
type
:
'required
'
,
value
:
'en
'
,
message
:
'语言必选
'
,
},
},
],
],
},
},
...
@@ -71,14 +112,11 @@ const ManagementForm = reactive({
...
@@ -71,14 +112,11 @@ const ManagementForm = reactive({
value
:
''
,
value
:
''
,
align
:
'left'
,
align
:
'left'
,
audio
:
true
,
audio
:
true
,
options
:
[
options
:
voice_list
,
rules
:
[
{
{
label
:
'小微 (直播间专属)'
,
type
:
'required'
,
value
:
'123'
,
message
:
'语音必选'
,
},
{
label
:
'小爱 (直播间专属)'
,
value
:
'12345'
,
},
},
],
],
},
},
...
@@ -91,34 +129,45 @@ const ManagementForm = reactive({
...
@@ -91,34 +129,45 @@ const ManagementForm = reactive({
{
{
type
:
'textarea'
,
type
:
'textarea'
,
label
:
'回复内容'
,
label
:
'回复内容'
,
name
:
'
product_30
'
,
name
:
'
manual
'
,
placeholder
:
'请输入语音内容'
,
placeholder
:
'请输入语音内容'
,
value
:
''
,
value
:
''
,
rules
:
[
{
type
:
'required'
,
message
:
'回复内容必填'
,
},
],
},
{
type
:
'text'
,
label
:
'hash'
,
name
:
'hash'
,
value
:
''
,
is_hidden
:
true
,
rules
:
[
{
type
:
'required'
,
message
:
'缺少hash'
,
},
],
},
},
],
],
},
},
],
],
});
});
const
getEditData
=
()
=>
{
let
local_data
=
getLocalData
(
live_stream_edit
,
'session'
);
if
(
!
local_data
)
{
// 没有本地数据,返回页面
show_message
(
'禁止访问'
);
// 返回话术管理
router
.
replace
({
path
:
'/AILiveStreaming/DiscourseManagement'
,
});
}
else
{
// 有数据--填充到form表单里
// ManagementForm.form
console
.
log
(
local_data
);
}
};
onBeforeMount
(()
=>
{
onBeforeMount
(()
=>
{
// 本地是否有缓存
// 本地是否有缓存
getEditData
();
const
row
=
getEditLocalData
(
live_stream_reply
,
ManagementForm
.
back_url
);
if
(
row
.
hash
)
{
EditFillData
(
ManagementForm
.
form_options
,
{
hash
:
row
.
hash
,
});
}
if
(
row
.
status
===
'2'
)
{
ManagementForm
.
is_send
.
disabled
=
false
;
}
});
});
</
script
>
</
script
>
...
...
src/utils/api/ai.ts
View file @
43de7cb4
...
@@ -241,6 +241,15 @@ export const LiveStreamTableDelete = (data: any) => {
...
@@ -241,6 +241,15 @@ export const LiveStreamTableDelete = (data: any) => {
});
});
};
};
// 人工回复
export
const
LiveStreamTaskManual
=
(
data
:
any
)
=>
{
return
request
.
post
(
'/api/voices/add-task-manual'
,
data
,
{
headers
:
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
},
});
};
/**
/**
* 直播管理 end
* 直播管理 end
*/
*/
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