Commit b3bb85bf by haojie

1

parent a632b5ee
declare interface Window { declare interface Window {
py_event: any; pyEvent: any;
} }
<template> <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"> <div class="img-box" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
<img :src="img" alt="" /> <img :src="img" alt="" />
<div v-show="showHover"> <div v-show="showHover">
......
...@@ -29,12 +29,13 @@ import ChangeName from '@/components/changeName.vue'; ...@@ -29,12 +29,13 @@ import ChangeName from '@/components/changeName.vue';
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
id: string | number; id: string | number;
img: string; img?: string;
value: string; value: string;
created_at: string; created_at: string;
clicked?: boolean; clicked?: boolean;
}>(), }>(),
{ {
img: '',
clicked: true, clicked: true,
customLast: true, customLast: true,
}, },
......
<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>
...@@ -2,16 +2,18 @@ ...@@ -2,16 +2,18 @@
<div class="my-digtal-people"> <div class="my-digtal-people">
<div class="card-item-list"> <div class="card-item-list">
<template v-for="item in myDigtalList.list" :key="item.id"> <template v-for="item in myDigtalList.list" :key="item.id">
<CardTwo :id="item.id" :img="item.img" :created_at="item.created_at" :value="item.value"> <CardTwo :id="item.id" :img="item.cover_url" :created_at="item.updated_at" :value="item.name">
<template #hover> <template #hover>
<div class="my-digtal-people-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 class="digtal-people-start-end" theme="danger" height="40px" @click="startLive(item)"
>开启直播</Button >开启直播</Button
> >
</template> </template>
<template v-else> <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> </template>
<div class="digtal-people-hover-tool"> <div class="digtal-people-hover-tool">
<Button size="13" theme="dark">编辑</Button> <Button size="13" theme="dark">编辑</Button>
...@@ -28,30 +30,18 @@ ...@@ -28,30 +30,18 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive } from 'vue'; import { onMounted, reactive } from 'vue';
import CardTwo from '@/components/cardTwo.vue'; import CardTwo from '@/components/cardTwo.vue';
import CustomLoading from '@/components/loading.vue'; import CustomLoading from '@/components/loading.vue';
import Button from '@/components/Button.vue'; import Button from '@/components/Button.vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import routerConfig from '@/router/tool'; import routerConfig from '@/router/tool';
import { getLiveTask } from '@/utils/api/userApi';
const router = useRouter(); 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({ const myDigtalList = reactive({
list: createList(), list: [],
loading: false, loading: false,
}); });
...@@ -62,9 +52,27 @@ const startLive = (item: any) => { ...@@ -62,9 +52,27 @@ const startLive = (item: any) => {
name: routerConfig.startLive.name, name: routerConfig.startLive.name,
query: { query: {
id: item.id, 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> </script>
<style lang="less"> <style lang="less">
......
...@@ -25,11 +25,12 @@ ...@@ -25,11 +25,12 @@
</div> </div>
<div class="digital-people-list"> <div class="digital-people-list">
<template v-for="(item, index) in digitalPeopleList.list" :key="item.id"> <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"> <template v-if="index === digitalPeopleList.list.length - 1">
<div class="more-choices">更多选择 ></div> <div class="more-choices" @click="digitalPeopleDialogVisible = true">更多选择 ></div>
</template> </template>
</template> </template>
<Loading v-show="digitalPeopleList.loading"></Loading>
</div> </div>
</div> </div>
</div> </div>
...@@ -48,11 +49,18 @@ ...@@ -48,11 +49,18 @@
</div> </div>
</template> </template>
</CustomDialog> </CustomDialog>
<DigitalPeopleDiaog
v-model="digitalPeopleDialogVisible"
:adminList="digitalPeopleList.adminList"
:myList="digitalPeopleList.myList"
></DigitalPeopleDiaog>
</div> </div>
</template> </template>
<script lang="tsx" setup> <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 CardOne from '@/components/cardOne.vue';
import CustomTabs from '@/components/CustomTabs'; import CustomTabs from '@/components/CustomTabs';
import CustomTabPanel from '@/components/CustomTabPanel'; import CustomTabPanel from '@/components/CustomTabPanel';
...@@ -63,6 +71,7 @@ import CustomInput from '@/components/input/index.vue'; ...@@ -63,6 +71,7 @@ import CustomInput from '@/components/input/index.vue';
import routerConfig from '@/router/tool'; import routerConfig from '@/router/tool';
import { show_message } from '@/utils/tool'; import { show_message } from '@/utils/tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { getDigitalPeopleList } from '@/service/Common';
const router = useRouter(); const router = useRouter();
...@@ -70,6 +79,8 @@ const router = useRouter(); ...@@ -70,6 +79,8 @@ const router = useRouter();
const currentTab = ref('1'); const currentTab = ref('1');
// 弹窗状态 // 弹窗状态
const dialogVisible = ref(false); const dialogVisible = ref(false);
// 选择数字人弹窗
const digitalPeopleDialogVisible = ref(false);
// 当前选择的数字人id // 当前选择的数字人id
const currentCard = ref<number | string>(); const currentCard = ref<number | string>();
// 直播名称 // 直播名称
...@@ -124,7 +135,10 @@ const choseList = (list: any[]) => { ...@@ -124,7 +135,10 @@ const choseList = (list: any[]) => {
// 数字人列表 // 数字人列表
const digitalPeopleList = reactive({ const digitalPeopleList = reactive({
list: createList(), list: [],
adminList: [],
myList: [],
loading: false,
}); });
// 数字人点击事件 // 数字人点击事件
...@@ -145,6 +159,29 @@ const dialogConfirm = () => { ...@@ -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> </script>
<style lang="less"> <style lang="less">
...@@ -156,7 +193,7 @@ const dialogConfirm = () => { ...@@ -156,7 +193,7 @@ const dialogConfirm = () => {
.label { .label {
font-size: @size-24; font-size: @size-24;
font-weight: 700; font-weight: 700;
color: #191919; color: white;
} }
.tips { .tips {
font-size: @size-14; font-size: @size-14;
...@@ -194,6 +231,8 @@ const dialogConfirm = () => { ...@@ -194,6 +231,8 @@ const dialogConfirm = () => {
background: #303030; background: #303030;
padding: 33px 30px 0px 30px; padding: 33px 30px 0px 30px;
border-radius: 6px; border-radius: 6px;
display: flex;
flex-direction: column;
.tool-line { .tool-line {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -208,6 +247,8 @@ const dialogConfirm = () => { ...@@ -208,6 +247,8 @@ const dialogConfirm = () => {
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
margin-left: -24px; margin-left: -24px;
position: relative;
flex: 1;
& > * { & > * {
margin-left: 24px; margin-left: 24px;
} }
......
...@@ -63,7 +63,9 @@ import { show_message } from '@/utils/tool'; ...@@ -63,7 +63,9 @@ import { show_message } from '@/utils/tool';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { setRememberList, getRememberList } from '@/utils/remember'; import { setRememberList, getRememberList } from '@/utils/remember';
import { UserLogin } from '@/utils/api/userApi'; import { UserLogin } from '@/utils/api/userApi';
import { useRouter } from 'vue-router';
const store = useStore(); const store = useStore();
const router = useRouter();
const loading = ref(false); const loading = ref(false);
......
...@@ -12,16 +12,19 @@ import request from '@/utils/otherRequest'; ...@@ -12,16 +12,19 @@ import request from '@/utils/otherRequest';
import Video from './components/video.vue'; import Video from './components/video.vue';
import Audio from './components/audio.vue'; import Audio from './components/audio.vue';
import Human from './components/human.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({ const liveInfo = reactive({
// 原始链接 // 原始链接
video: [ 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',
],
// 音频从视频中提取出来 // 音频从视频中提取出来
audio: '', audio: '',
scriptText: '1111', content: '',
status: 1, status: 1,
startTime: '00:50:00', startTime: '00:50:00',
}); });
...@@ -32,7 +35,10 @@ const realVideo = ref(''); ...@@ -32,7 +35,10 @@ const realVideo = ref('');
const realAudio = ref(''); const realAudio = ref('');
const getVideo = (url: string) => { const getVideo = (url: string) => {
return request.get(url); return request.get(url, {
responseType: 'blob',
headers: {},
});
}; };
const installVideo = async () => { const installVideo = async () => {
...@@ -44,15 +50,58 @@ const installVideo = async () => { ...@@ -44,15 +50,58 @@ const installVideo = async () => {
let res: any = await request.all(list); let res: any = await request.all(list);
if (res && res.length) { if (res && res.length) {
// 通知python合并 // 通知python合并
console.log(res); liveInfo.video = res;
submitVideo();
} else {
show_message('获取视频错误');
} }
} catch (e) { } catch (e) {
show_message('获取视频错误');
console.log(e); 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(); installVideo();
}); });
</script> </script>
......
import { getDigitalPersonList } from '@/utils/api/userApi';
export const getUploadConfig = async () => { export const getUploadConfig = async () => {
return {}; 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;
}
};
// 直播状态
export const liveStatusNotBroadcast = 0; // 未开播
export const liveStatusAlready = 1; // 已开播
...@@ -2,8 +2,16 @@ import request from '@/utils/request'; ...@@ -2,8 +2,16 @@ import request from '@/utils/request';
import store from '@/store'; import store from '@/store';
// 获取cookie // 获取cookie
export const getUserCookie = () => { export const getUserCookie = () => {
// console.log(store.getters['user/token']);
return store.getters['user/token']; return store.getters['user/token'];
}; };
export const getHeader = () => {
return {
authorization: `Bearer ${getUserCookie()}`,
};
};
// 获取语言 // 获取语言
export const getLanguage = () => { export const getLanguage = () => {
return store.getters['language/getLang']; return store.getters['language/getLang'];
...@@ -14,13 +22,43 @@ export const UserLogin = (data: any) => { ...@@ -14,13 +22,43 @@ export const UserLogin = (data: any) => {
return request.post('/api/login', data); return request.post('/api/login', data);
}; };
// 用户余额 // 获取数字人列表
export const getUserBalance = (data: any) => { export const getDigitalPersonList = () => {
const token = store.getters['user/token']; const header = getHeader();
return request.get('/api/users/balance', { return request.get('/api/live/digital-man', {
...data, 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: { headers: {
authorization: `Bearer ${token}`, ...header,
}, },
}); });
}; };
......
...@@ -2,7 +2,7 @@ import axios from 'axios'; ...@@ -2,7 +2,7 @@ import axios from 'axios';
import { MessagePlugin } from 'tdesign-vue-next'; import { MessagePlugin } from 'tdesign-vue-next';
const instance: any = axios.create({ const instance: any = axios.create({
timeout: 6000000, timeout: 60000,
withCredentials: false, withCredentials: false,
}); });
instance.all = axios.all; instance.all = axios.all;
......
...@@ -2,7 +2,7 @@ export const initPyqtToWindow = (key: string = '') => { ...@@ -2,7 +2,7 @@ export const initPyqtToWindow = (key: string = '') => {
if (key) { if (key) {
window[key] = {}; window[key] = {};
} else { } else {
window.py_event = {}; window.pyEvent = {};
} }
}; };
...@@ -11,6 +11,6 @@ export const injectWindow = (key: string, value: any, parent: string = '') => { ...@@ -11,6 +11,6 @@ export const injectWindow = (key: string, value: any, parent: string = '') => {
if (parent) { if (parent) {
window[parent][key] = value; window[parent][key] = value;
} else { } else {
window.py_event[key] = value; window.pyEvent[key] = value;
} }
}; };
...@@ -46,10 +46,8 @@ instance.interceptors.response.use( ...@@ -46,10 +46,8 @@ instance.interceptors.response.use(
}, },
(err) => { (err) => {
if ('response' in err && err['response']) { if ('response' in err && err['response']) {
const { message: msg, status_code } = err.response.data; const { status, data } = err.response;
if (status_code == 403) { if (status == 401) {
MessagePlugin.closeAll();
// MessagePlugin.warning(i18n.global.t('message.loginInfo'));
router.push({ router.push({
path: '/login', path: '/login',
}); });
...@@ -59,8 +57,7 @@ instance.interceptors.response.use( ...@@ -59,8 +57,7 @@ instance.interceptors.response.use(
store.commit('user/removeBindInfo'); store.commit('user/removeBindInfo');
return; return;
} }
MessagePlugin.closeAll(); show_message(data.message || i18n.global.t('message.error'), 'error');
MessagePlugin.error(msg || i18n.global.t('message.error'));
return err.response; return err.response;
} else { } else {
// 格式不一致的 // 格式不一致的
......
...@@ -444,3 +444,9 @@ export const createTestData = (obj: any, num: number = 20) => { ...@@ -444,3 +444,9 @@ export const createTestData = (obj: any, num: number = 20) => {
} }
return list; return list;
}; };
// 是否本地环境
export const isDev = () => {
const is_dev = import.meta.env.MODE;
return is_dev === 'development' ? true : false;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment