Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
live-management-web
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
live-management-web
Commits
b3bb85bf
Commit
b3bb85bf
authored
Jul 13, 2023
by
haojie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
a632b5ee
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
371 additions
and
50 deletions
+371
-50
lib.dom.d.ts
+1
-1
src/components/cardOne.vue
+1
-1
src/components/cardTwo.vue
+2
-1
src/pages/home/components/digitalPeopleDiaog.vue
+153
-0
src/pages/home/components/myDigtalPeople.vue
+26
-18
src/pages/home/index.vue
+46
-5
src/pages/login/index.vue
+2
-0
src/pages/startLive/index.vue
+58
-9
src/service/Common.ts
+23
-0
src/service/Live.ts
+3
-0
src/utils/api/userApi.ts
+44
-6
src/utils/otherRequest.ts
+1
-1
src/utils/pyqt.ts
+2
-2
src/utils/request.ts
+3
-6
src/utils/tool.ts
+6
-0
No files found.
lib.dom.d.ts
View file @
b3bb85bf
declare
interface
Window
{
py
_e
vent
:
any
;
py
E
vent
:
any
;
}
src/components/cardOne.vue
View file @
b3bb85bf
<
template
>
<div
class=
"custom-card-box"
@
click=
"onChange"
:class=
"[clicked ? 'cursor-pointer' : '', className]"
>
<div
class=
"custom-card-box"
@
click=
"onChange"
:class=
"[clicked ? 'cursor-pointer' : '', className
? className : ''
]"
>
<div
class=
"img-box"
@
mouseenter=
"handleMouseEnter"
@
mouseleave=
"handleMouseLeave"
>
<img
:src=
"img"
alt=
""
/>
<div
v-show=
"showHover"
>
...
...
src/components/cardTwo.vue
View file @
b3bb85bf
...
...
@@ -29,12 +29,13 @@ import ChangeName from '@/components/changeName.vue';
const
props
=
withDefaults
(
defineProps
<
{
id
:
string
|
number
;
img
:
string
;
img
?
:
string
;
value
:
string
;
created_at
:
string
;
clicked
?:
boolean
;
}
>
(),
{
img
:
''
,
clicked
:
true
,
customLast
:
true
,
},
...
...
src/pages/home/components/digitalPeopleDiaog.vue
0 → 100644
View file @
b3bb85bf
<
template
>
<Dialog
v-model=
"visible"
className=
"chose-person-dialog"
@
confirm=
"confirm"
>
<div
class=
"chose-person-dialog-body"
>
<div
class=
"header"
>
选择数字人
</div>
<div
class=
"group-btns"
>
<template
v-for=
"item in groupBtns"
:key=
"item.value"
>
<Button
theme=
"opacity"
class=
"default-chose-person-btn"
@
click=
"changeBtn(item)"
:class=
"
{
'btn-active': item.value === currentBtn,
}"
>
{{
item
.
label
}}
</Button
>
</
template
>
</div>
<div
class=
"person-list"
>
<
template
v-if=
"currentBtn == '1'"
>
<div
class=
""
v-for=
"item in adminList"
:key=
"item.id"
>
<CardOne
:className=
"item.id == currentCard ? 'card-active' : ''"
:img=
"item.cover_url"
:id=
"item.id"
:name=
"item.name"
@
change=
"cardChange"
></CardOne>
</div>
</
template
>
<
template
v-if=
"currentBtn == '2'"
>
<div
class=
""
v-for=
"item in myList"
:key=
"item.id"
>
<CardOne
:className=
"item.id == currentCard ? 'card-active' : ''"
:img=
"item.cover_url"
:id=
"item.id"
:name=
"item.name"
@
change=
"cardChange"
></CardOne>
</div>
</
template
>
</div>
</div>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
CardOne
from
'@/components/cardOne.vue'
;
import
Button
from
'@/components/Button.vue'
;
import
Dialog
from
'@/components/Dialog.vue'
;
import
{
ref
,
watch
}
from
'vue'
;
import
{
useRouter
}
from
'vue-router'
;
import
routerConfig
from
'@/router/tool'
;
const
props
=
withDefaults
(
defineProps
<
{
modelValue
:
boolean
;
adminList
:
any
[];
myList
:
any
[];
}
>
(),
{},
);
const
emit
=
defineEmits
([
'update:modelValue'
]);
const
visible
=
ref
(
props
.
modelValue
);
const
router
=
useRouter
();
// 当前选择的数字人
const
currentCard
=
ref
(
''
);
const
cardChange
=
(
id
:
any
)
=>
{
currentCard
.
value
=
id
;
};
//
const
currentBtn
=
ref
(
'1'
);
const
groupBtns
=
[
{
label
:
'数字人库'
,
value
:
'1'
,
},
{
label
:
'我的数字人'
,
value
:
'2'
,
},
];
const
changeBtn
=
(
item
:
any
)
=>
{
currentBtn
.
value
=
item
.
value
;
};
// 确认
const
confirm
=
()
=>
{
visible
.
value
=
false
;
router
.
push
({
path
:
routerConfig
.
createLive
.
path
,
name
:
routerConfig
.
createLive
.
name
,
query
:
{
id
:
currentCard
.
value
,
title
:
''
,
},
});
};
watch
(
()
=>
props
.
modelValue
,
(
v
)
=>
{
visible
.
value
=
v
;
},
);
watch
(
()
=>
visible
.
value
,
(
v
)
=>
{
emit
(
'update:modelValue'
,
v
);
},
);
</
script
>
<
style
lang=
"less"
>
@import
'@/style/variables'
;
.chose-person-dialog
{
.t-dialog
{
width
:
1000px
;
}
}
.chose-person-dialog-body
{
.header
{
text-align
:
center
;
color
:
#fff
;
font-size
:
@
size-16
;
}
.group-btns
{
margin-top
:
12px
;
.default-chose-person-btn
{
height
:
27px
!important
;
font-size
:
@
size-13
;
}
.btn-active
{
border
:
1px
solid
#04ae8a
;
background
:
#04ae8a
;
&:hover
{
border
:
1px
solid
#04ae8a
;
background
:
#04ae8a
;
}
}
}
.person-list
{
margin-top
:
12px
;
.card-active
{
border
:
1px
solid
#04ae8a
;
}
}
}
</
style
>
src/pages/home/components/myDigtalPeople.vue
View file @
b3bb85bf
...
...
@@ -2,16 +2,18 @@
<div
class=
"my-digtal-people"
>
<div
class=
"card-item-list"
>
<template
v-for=
"item in myDigtalList.list"
:key=
"item.id"
>
<CardTwo
:id=
"item.id"
:img=
"item.
img"
:created_at=
"item.created_at"
:value=
"item.valu
e"
>
<CardTwo
:id=
"item.id"
:img=
"item.
cover_url"
:created_at=
"item.updated_at"
:value=
"item.nam
e"
>
<template
#
hover
>
<div
class=
"my-digtal-people-hover"
>
<template
v-if=
"
true
"
>
<template
v-if=
"
item.status == 0
"
>
<Button
class=
"digtal-people-start-end"
theme=
"danger"
height=
"40px"
@
click=
"startLive(item)"
>
开启直播
</Button
>
</
template
>
<
template
v-else
>
<Button
class=
"digtal-people-start-end"
theme=
"danger"
height=
"40px"
>
关闭直播
</Button>
<Button
class=
"digtal-people-start-end"
theme=
"danger"
height=
"40px"
@
click=
"startLive(item)"
>
关闭直播
</Button
>
</
template
>
<div
class=
"digtal-people-hover-tool"
>
<Button
size=
"13"
theme=
"dark"
>
编辑
</Button>
...
...
@@ -28,30 +30,18 @@
</template>
<
script
lang=
"ts"
setup
>
import
{
reactive
}
from
'vue'
;
import
{
onMounted
,
reactive
}
from
'vue'
;
import
CardTwo
from
'@/components/cardTwo.vue'
;
import
CustomLoading
from
'@/components/loading.vue'
;
import
Button
from
'@/components/Button.vue'
;
import
{
useRouter
}
from
'vue-router'
;
import
routerConfig
from
'@/router/tool'
;
import
{
getLiveTask
}
from
'@/utils/api/userApi'
;
const
router
=
useRouter
();
const
createList
=
()
=>
{
let
list
=
[];
for
(
let
i
=
0
;
i
<
20
;
i
++
)
{
list
.
push
({
id
:
1
,
img
:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s'
,
value
:
'123456'
,
created_at
:
'2023-7-1 16:05'
,
});
}
return
list
;
};
const
myDigtalList
=
reactive
({
list
:
createList
()
,
list
:
[]
,
loading
:
false
,
});
...
...
@@ -62,9 +52,27 @@ const startLive = (item: any) => {
name
:
routerConfig
.
startLive
.
name
,
query
:
{
id
:
item
.
id
,
status
:
item
.
status
,
},
});
};
const
getList
=
async
()
=>
{
try
{
myDigtalList
.
loading
=
true
;
let
res
:
any
=
await
getLiveTask
();
if
(
res
.
code
==
0
)
{
myDigtalList
.
list
=
res
.
data
;
}
myDigtalList
.
loading
=
false
;
}
catch
(
e
)
{
console
.
log
(
e
);
myDigtalList
.
loading
=
false
;
}
};
onMounted
(()
=>
{
getList
();
});
</
script
>
<
style
lang=
"less"
>
...
...
src/pages/home/index.vue
View file @
b3bb85bf
...
...
@@ -25,11 +25,12 @@
</div>
<div
class=
"digital-people-list"
>
<
template
v-for=
"(item, index) in digitalPeopleList.list"
:key=
"item.id"
>
<CardOne
:id=
"item.id"
:img=
"item.
img
"
:name=
"item.name"
@
change=
"cardClick"
></CardOne>
<CardOne
:id=
"item.id"
:img=
"item.
cover_url
"
:name=
"item.name"
@
change=
"cardClick"
></CardOne>
<template
v-if=
"index === digitalPeopleList.list.length - 1"
>
<div
class=
"more-choices"
>
更多选择 >
</div>
<div
class=
"more-choices"
@
click=
"digitalPeopleDialogVisible = true"
>
更多选择 >
</div>
</
template
>
</template>
<Loading
v-show=
"digitalPeopleList.loading"
></Loading>
</div>
</div>
</div>
...
...
@@ -48,11 +49,18 @@
</div>
</
template
>
</CustomDialog>
<DigitalPeopleDiaog
v-model=
"digitalPeopleDialogVisible"
:adminList=
"digitalPeopleList.adminList"
:myList=
"digitalPeopleList.myList"
></DigitalPeopleDiaog>
</div>
</template>
<
script
lang=
"tsx"
setup
>
import
{
reactive
,
ref
}
from
'vue'
;
import
{
onMounted
,
reactive
,
ref
}
from
'vue'
;
import
Loading
from
'@/components/loading.vue'
;
import
DigitalPeopleDiaog
from
'./components/digitalPeopleDiaog.vue'
;
import
CardOne
from
'@/components/cardOne.vue'
;
import
CustomTabs
from
'@/components/CustomTabs'
;
import
CustomTabPanel
from
'@/components/CustomTabPanel'
;
...
...
@@ -63,6 +71,7 @@ import CustomInput from '@/components/input/index.vue';
import
routerConfig
from
'@/router/tool'
;
import
{
show_message
}
from
'@/utils/tool'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
getDigitalPeopleList
}
from
'@/service/Common'
;
const
router
=
useRouter
();
...
...
@@ -70,6 +79,8 @@ const router = useRouter();
const
currentTab
=
ref
(
'1'
);
// 弹窗状态
const
dialogVisible
=
ref
(
false
);
// 选择数字人弹窗
const
digitalPeopleDialogVisible
=
ref
(
false
);
// 当前选择的数字人id
const
currentCard
=
ref
<
number
|
string
>
();
// 直播名称
...
...
@@ -124,7 +135,10 @@ const choseList = (list: any[]) => {
// 数字人列表
const
digitalPeopleList
=
reactive
({
list
:
createList
(),
list
:
[],
adminList
:
[],
myList
:
[],
loading
:
false
,
});
// 数字人点击事件
...
...
@@ -145,6 +159,29 @@ const dialogConfirm = () => {
},
});
};
const
getList
=
async
()
=>
{
try
{
digitalPeopleList
.
loading
=
true
;
let
res
=
await
getDigitalPeopleList
();
digitalPeopleList
.
adminList
=
res
.
adminList
;
digitalPeopleList
.
myList
=
res
.
myList
;
if
(
digitalPeopleList
.
myList
.
length
>
5
)
{
digitalPeopleList
.
list
=
digitalPeopleList
.
myList
.
slice
(
0
,
5
);
}
else
{
digitalPeopleList
.
list
=
digitalPeopleList
.
myList
.
concat
(
digitalPeopleList
.
adminList
);
}
digitalPeopleList
.
loading
=
false
;
}
catch
(
e
)
{
console
.
log
(
e
);
digitalPeopleList
.
loading
=
false
;
}
};
onMounted
(()
=>
{
//
getList
();
});
</
script
>
<
style
lang=
"less"
>
...
...
@@ -156,7 +193,7 @@ const dialogConfirm = () => {
.label
{
font-size
:
@
size-24
;
font-weight
:
700
;
color
:
#191919
;
color
:
white
;
}
.tips
{
font-size
:
@
size-14
;
...
...
@@ -194,6 +231,8 @@ const dialogConfirm = () => {
background
:
#303030
;
padding
:
33px
30px
0px
30px
;
border-radius
:
6px
;
display
:
flex
;
flex-direction
:
column
;
.tool-line
{
display
:
flex
;
justify-content
:
space-between
;
...
...
@@ -208,6 +247,8 @@ const dialogConfirm = () => {
margin-top
:
20px
;
display
:
flex
;
margin-left
:
-24px
;
position
:
relative
;
flex
:
1
;
&
>
*
{
margin-left
:
24px
;
}
...
...
src/pages/login/index.vue
View file @
b3bb85bf
...
...
@@ -63,7 +63,9 @@ import { show_message } from '@/utils/tool';
import
{
useStore
}
from
'vuex'
;
import
{
setRememberList
,
getRememberList
}
from
'@/utils/remember'
;
import
{
UserLogin
}
from
'@/utils/api/userApi'
;
import
{
useRouter
}
from
'vue-router'
;
const
store
=
useStore
();
const
router
=
useRouter
();
const
loading
=
ref
(
false
);
...
...
src/pages/startLive/index.vue
View file @
b3bb85bf
...
...
@@ -12,16 +12,19 @@ import request from '@/utils/otherRequest';
import
Video
from
'./components/video.vue'
;
import
Audio
from
'./components/audio.vue'
;
import
Human
from
'./components/human.vue'
;
import
{
getLiveDetail
}
from
'@/utils/api/userApi'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
show_message
,
isDev
}
from
'@/utils/tool'
;
import
{
initPyqtToWindow
,
injectWindow
}
from
'@/utils/pyqt'
;
const
route
=
useRoute
();
const
routeQuery
=
route
.
query
;
const
liveInfo
=
reactive
({
// 原始链接
video
:
[
'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/cea8fe95-bf49-480b-ac79-c95fcd3be26f.mp4'
,
'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/cea8fe95-bf49-480b-ac79-c95fcd3be26f.mp4'
,
],
video
:
[],
// 音频从视频中提取出来
audio
:
''
,
scriptText
:
'1111
'
,
content
:
'
'
,
status
:
1
,
startTime
:
'00:50:00'
,
});
...
...
@@ -32,7 +35,10 @@ const realVideo = ref('');
const
realAudio
=
ref
(
''
);
const
getVideo
=
(
url
:
string
)
=>
{
return
request
.
get
(
url
);
return
request
.
get
(
url
,
{
responseType
:
'blob'
,
headers
:
{},
});
};
const
installVideo
=
async
()
=>
{
...
...
@@ -44,15 +50,58 @@ const installVideo = async () => {
let
res
:
any
=
await
request
.
all
(
list
);
if
(
res
&&
res
.
length
)
{
// 通知python合并
console
.
log
(
res
);
liveInfo
.
video
=
res
;
submitVideo
();
}
else
{
show_message
(
'获取视频错误'
);
}
}
catch
(
e
)
{
show_message
(
'获取视频错误'
);
console
.
log
(
e
);
}
};
onMounted
(()
=>
{
// 下载视频
const
getDetail
=
async
()
=>
{
if
(
!
routeQuery
.
id
)
{
show_message
(
'禁止访问'
);
return
;
}
try
{
let
res
:
any
=
await
getLiveDetail
(
routeQuery
.
id
);
if
(
res
.
code
==
0
)
{
liveInfo
.
video
=
res
.
data
.
url
;
liveInfo
.
content
=
res
.
data
.
content
;
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 视频列表提交到py
const
submitVideo
=
()
=>
{
try
{
window
.
pyjs
.
submitVideo
(
liveInfo
.
video
);
}
catch
(
e
)
{
show_message
(
e
);
}
};
// python 回调
const
mergeCallback
=
(
video
:
any
,
audio
:
any
)
=>
{
if
(
!
video
)
{
show_message
(
'没有接收到视频'
);
}
if
(
!
audio
)
{
show_message
(
'没有接收到音频'
);
}
show_message
(
'已全部接收'
,
'success'
);
};
onMounted
(
async
()
=>
{
initPyqtToWindow
();
// 将通知方法注入window
injectWindow
(
'mergeCallback'
,
mergeCallback
);
await
getDetail
();
installVideo
();
});
</
script
>
...
...
src/service/Common.ts
View file @
b3bb85bf
import
{
getDigitalPersonList
}
from
'@/utils/api/userApi'
;
export
const
getUploadConfig
=
async
()
=>
{
return
{};
};
// 获取数字人列表
export
const
getDigitalPeopleList
=
async
()
=>
{
let
obj
=
{
adminList
:
[],
myList
:
[],
};
try
{
let
res
:
any
=
await
getDigitalPersonList
();
if
(
res
.
code
==
0
)
{
// 后台数字人
obj
.
adminList
=
res
.
data
.
filter
((
item
:
any
)
=>
item
.
users_id
==
0
);
// 我的数字人
obj
.
myList
=
res
.
data
.
filter
((
item
:
any
)
=>
item
.
users_id
!=
0
);
}
return
obj
;
}
catch
(
e
)
{
console
.
log
(
e
);
return
obj
;
}
};
src/service/Live.ts
0 → 100644
View file @
b3bb85bf
// 直播状态
export
const
liveStatusNotBroadcast
=
0
;
// 未开播
export
const
liveStatusAlready
=
1
;
// 已开播
src/utils/api/userApi.ts
View file @
b3bb85bf
...
...
@@ -2,8 +2,16 @@ import request from '@/utils/request';
import
store
from
'@/store'
;
// 获取cookie
export
const
getUserCookie
=
()
=>
{
// console.log(store.getters['user/token']);
return
store
.
getters
[
'user/token'
];
};
export
const
getHeader
=
()
=>
{
return
{
authorization
:
`Bearer
${
getUserCookie
()}
`
,
};
};
// 获取语言
export
const
getLanguage
=
()
=>
{
return
store
.
getters
[
'language/getLang'
];
...
...
@@ -14,13 +22,43 @@ export const UserLogin = (data: any) => {
return
request
.
post
(
'/api/login'
,
data
);
};
// 用户余额
export
const
getUserBalance
=
(
data
:
any
)
=>
{
const
token
=
store
.
getters
[
'user/token'
];
return
request
.
get
(
'/api/users/balance'
,
{
...
data
,
// 获取数字人列表
export
const
getDigitalPersonList
=
()
=>
{
const
header
=
getHeader
();
return
request
.
get
(
'/api/live/digital-man'
,
{
params
:
{},
headers
:
{
...
header
,
},
});
};
// 直播任务列表
export
const
getLiveTask
=
()
=>
{
const
header
=
getHeader
();
return
request
.
get
(
'/api/live/task'
,
{
headers
:
{
...
header
,
},
});
};
// 直播(编辑)
export
const
getLiveEdit
=
(
id
:
string
|
number
)
=>
{
const
header
=
getHeader
();
return
request
.
get
(
`/api/live/task/
${
id
}
`
,
{
headers
:
{
...
header
,
},
});
};
// 直播详情
export
const
getLiveDetail
=
(
id
:
string
|
number
)
=>
{
const
header
=
getHeader
();
return
request
.
get
(
`/api/live/task/
${
id
}
/generate`
,
{
headers
:
{
authorization
:
`Bearer
${
token
}
`
,
...
header
,
},
});
};
...
...
src/utils/otherRequest.ts
View file @
b3bb85bf
...
...
@@ -2,7 +2,7 @@ import axios from 'axios';
import
{
MessagePlugin
}
from
'tdesign-vue-next'
;
const
instance
:
any
=
axios
.
create
({
timeout
:
60000
00
,
timeout
:
60000
,
withCredentials
:
false
,
});
instance
.
all
=
axios
.
all
;
...
...
src/utils/pyqt.ts
View file @
b3bb85bf
...
...
@@ -2,7 +2,7 @@ export const initPyqtToWindow = (key: string = '') => {
if
(
key
)
{
window
[
key
]
=
{};
}
else
{
window
.
py
_e
vent
=
{};
window
.
py
E
vent
=
{};
}
};
...
...
@@ -11,6 +11,6 @@ export const injectWindow = (key: string, value: any, parent: string = '') => {
if
(
parent
)
{
window
[
parent
][
key
]
=
value
;
}
else
{
window
.
py
_e
vent
[
key
]
=
value
;
window
.
py
E
vent
[
key
]
=
value
;
}
};
src/utils/request.ts
View file @
b3bb85bf
...
...
@@ -46,10 +46,8 @@ instance.interceptors.response.use(
},
(
err
)
=>
{
if
(
'response'
in
err
&&
err
[
'response'
])
{
const
{
message
:
msg
,
status_code
}
=
err
.
response
.
data
;
if
(
status_code
==
403
)
{
MessagePlugin
.
closeAll
();
// MessagePlugin.warning(i18n.global.t('message.loginInfo'));
const
{
status
,
data
}
=
err
.
response
;
if
(
status
==
401
)
{
router
.
push
({
path
:
'/login'
,
});
...
...
@@ -59,8 +57,7 @@ instance.interceptors.response.use(
store
.
commit
(
'user/removeBindInfo'
);
return
;
}
MessagePlugin
.
closeAll
();
MessagePlugin
.
error
(
msg
||
i18n
.
global
.
t
(
'message.error'
));
show_message
(
data
.
message
||
i18n
.
global
.
t
(
'message.error'
),
'error'
);
return
err
.
response
;
}
else
{
// 格式不一致的
...
...
src/utils/tool.ts
View file @
b3bb85bf
...
...
@@ -444,3 +444,9 @@ export const createTestData = (obj: any, num: number = 20) => {
}
return
list
;
};
// 是否本地环境
export
const
isDev
=
()
=>
{
const
is_dev
=
import
.
meta
.
env
.
MODE
;
return
is_dev
===
'development'
?
true
:
false
;
};
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