Commit a632b5ee by haojie

1

parent 15f5c94a
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 6C16.8 6 6 16.8 6 30C6 43.2 16.8 54 30 54C43.2 54 54 43.2 54 30C54 16.8 43.2 6 30 6ZM40.8 37.8C41.7 38.7 41.7 39.9 40.8 40.8C39.9 41.7 38.7 41.7 37.8 40.8L30 33L22.2 40.8C21.3 41.7 20.1 41.7 19.2 40.8C18.3 39.9 18.3 38.7 19.2 37.8L27 30L19.2 22.2C18.3 21.3 18.3 20.1 19.2 19.2C20.1 18.3 21.3 18.3 22.2 19.2L30 27L37.8 19.2C38.7 18.3 39.9 18.3 40.8 19.2C41.7 20.1 41.7 21.3 40.8 22.2L33 30L40.8 37.8Z" fill="#FC384B"/>
</svg>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.4004 6.3999C17.1457 6.3999 6.40039 17.1452 6.40039 30.3999C6.40039 43.6546 17.1457 54.3999 30.4004 54.3999C43.6551 54.3999 54.4004 43.6546 54.4004 30.3999C54.4004 17.1452 43.6551 6.3999 30.4004 6.3999ZM44.7464 34.9599C44.7464 35.2935 44.476 35.5639 44.1424 35.5639H27.2057C26.9384 35.5639 26.7217 35.3472 26.7217 35.0799V35.0799V18.7522C26.7217 17.9144 27.4009 17.2352 28.2387 17.2352V17.2352C29.0765 17.2352 29.7557 17.9144 29.7557 18.7522V29.5306C29.7557 31.1874 31.0989 32.5306 32.7557 32.5306H42.3177C43.6593 32.5306 44.7468 33.6183 44.7464 34.9599V34.9599V34.9599Z" fill="#04AE8A"/>
</svg>
<svg width="59" height="59" viewBox="0 0 59 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.2163 0C13.1104 0 0 13.103 0 29.2163C0.00732422 45.3223 13.1104 58.4253 29.2163 58.4253C45.3223 58.4253 58.4253 45.3223 58.4253 29.2163C58.4253 13.1104 45.3223 0 29.2163 0ZM41.8872 30.9009L23.584 41.4697C22.2876 42.2168 20.6689 41.2793 20.6689 39.7852V18.6475C20.6689 17.1533 22.2876 16.2158 23.584 16.9629L41.8872 27.5317C43.1836 28.2788 43.1836 30.1538 41.8872 30.9009Z" fill="#00DDDD"/>
</svg>
\ No newline at end of file
<svg width="59" height="59" viewBox="0 0 59 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M50.3747 8.55561C45.2532 3.44951 38.414 0.433061 31.19 0.0940338C23.9659 -0.244993 16.8743 2.11768 11.2971 6.7217C5.71985 11.3257 2.05648 17.8412 1.02079 24.9987C-0.0149095 32.1562 1.65126 39.443 5.69464 45.4391C9.73802 51.4352 15.869 55.7112 22.8928 57.4339C29.9167 59.1565 37.3304 58.2025 43.6892 54.7576C50.0481 51.3127 54.8967 45.6238 57.2902 38.7993C59.6837 31.9748 59.4507 24.5037 56.6365 17.8416C55.1684 14.371 53.042 11.2176 50.3747 8.55561Z" fill="#FC384B"/>
</svg>
\ No newline at end of file
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 6C16.7451 6 6 16.7451 6 30C6 43.2549 16.7451 54 30 54C43.2549 54 54 43.2549 54 30C54 16.7451 43.2549 6 30 6ZM42.6262 24.3157L27.9432 38.9989C27.4855 39.4565 26.8857 39.6854 26.2859 39.6854C25.6861 39.6854 25.0863 39.4565 24.6286 38.9989L24.6273 38.9975L17.3738 31.7441C16.4585 30.8289 16.4585 29.3448 17.3738 28.4296C18.2891 27.5143 19.7731 27.5142 20.6885 28.4296L26.2859 34.027L39.3116 21.0012C40.2268 20.0859 41.7109 20.0859 42.6262 21.0012C43.5415 21.9165 43.5415 23.4004 42.6262 24.3157Z" fill="#04AE8A"/>
</svg>
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M53.345 52.3358L46.2906 45.2731C48.1248 42.7782 49.2105 39.6992 49.2105 36.3708C49.2105 28.0725 42.4672 21.321 34.1788 21.321C25.8905 21.321 19.1475 28.0725 19.1475 36.3708C19.1475 44.6692 25.8905 51.4206 34.1788 51.4206C37.5033 51.4206 40.5785 50.3337 43.0705 48.4972L50.1249 55.56C50.5697 56.0049 51.1522 56.2275 51.735 56.2275C52.3179 56.2275 52.9003 56.0049 53.3451 55.5599C54.2342 54.6694 54.2342 53.226 53.345 52.3358ZM34.1788 47.7163C27.9305 47.7163 22.8474 42.6266 22.8474 36.3708C22.8474 30.115 27.9305 25.0254 34.1788 25.0254C40.4271 25.0254 45.5106 30.1149 45.5106 36.3708C45.5105 42.6267 40.4271 47.7163 34.1788 47.7163Z" fill="#508BFE"/>
<path d="M14.7199 36.994C14.7199 26.3716 23.3203 17.7605 33.9295 17.7605C40.4264 17.7605 46.17 20.9898 49.6464 25.9327V7.27522C49.6464 5.34234 48.0799 3.77246 46.1475 3.77246H9.4872C7.55493 3.77246 5.98828 5.34066 5.98828 7.27516V52.7247C5.98828 54.6577 7.55481 56.2276 9.4872 56.2276H33.9295C23.3203 56.2276 14.7199 47.6164 14.7199 36.994ZM12.9736 10.7665C12.9736 9.80078 13.7555 9.01797 14.72 9.01797H40.9149C41.8793 9.01797 42.6612 9.80078 42.6612 10.7665C42.6612 11.7321 41.8794 12.515 40.9149 12.515H14.7199C13.7555 12.515 12.9736 11.7321 12.9736 10.7665Z" fill="#508BFE"/>
</svg>
......@@ -5,6 +5,7 @@
background: bk,
}"
>
<template v-if="mode === '1'">
<template v-if="clickPlay">
<img :src="imgs.start" alt="" class="play-icon" @click="onPlay" v-show="!playStatus" />
<img :src="imgs.stop" alt="" class="play-icon" @click="onPause" v-show="playStatus" />
......@@ -15,6 +16,26 @@
<div class="play-current-progress" :style="{ width: `${playProgress}%` }"></div>
</div>
</template>
</template>
<template v-else-if="mode === '2'">
<div class="mode-2-audio">
<div>
<img :src="imgs.start" alt="" class="play-icon" @click="onPlay" v-show="!playStatus" />
<img :src="imgs.stop" alt="" class="play-icon" @click="onPause" v-show="playStatus" />
</div>
<div>
<span class="play-time"> {{ transTime(audioCurrent) }}/{{ transTime(audioDuration) }} </span>
</div>
</div>
</template>
<template v-else-if="mode === '3'">
<div class="mode-3-audio">
<div>
<img :src="imgs.start" alt="" class="play-icon" @click="onPlay" v-show="!playStatus" />
<img :src="imgs.stop" alt="" class="play-icon" @click="onPause" v-show="playStatus" />
</div>
</div>
</template>
</div>
<audio ref="audioRef" :src="CurrentUrl()" @canplay="onCanplay"></audio>
......@@ -29,6 +50,7 @@ const props = withDefaults(
bk?: string;
autoPlay?: boolean;
clickPlay?: boolean;
mode?: string;
}>(),
{
need_progress: true,
......@@ -36,12 +58,13 @@ const props = withDefaults(
bk: 'transparent',
autoPlay: false,
clickPlay: false,
mode: '1',
},
);
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,
start: new URL('../assets/svg/custom/startAudio.svg', import.meta.url).href,
stop: new URL('../assets/svg/custom/stopAudio.svg', import.meta.url).href,
};
// const speedList = [
......@@ -200,6 +223,11 @@ const formatTime = (value: string) => {
justify-content: center;
align-items: center;
color: #fff;
.mode-2-audio {
.dja();
flex-direction: column;
}
.play-icon {
width: 34px;
height: 34px;
......@@ -241,5 +269,12 @@ const formatTime = (value: string) => {
cursor: pointer;
color: #00e5ff;
}
.mode-3-audio {
img {
width: 60px !important;
height: 60px !important;
}
}
}
</style>
......@@ -34,6 +34,13 @@
font-size: @size-15;
}
}
//
.c-nav-item-dark2 {
.c-tabs__nav-item-wrapper {
color: #b4b4b4;
font-size: @size-20;
}
}
.c-nav-item_active {
background: white;
transition: all 0.2s;
......@@ -48,5 +55,12 @@
color: #04ae8a;
}
}
.c-nav-item-_active_dark2 {
background: #303030;
transition: all 0.2s;
.c-tabs__nav-item-wrapper {
color: #fff;
}
}
}
}
......@@ -104,6 +104,8 @@ export default defineComponent({
if (props.modelValue === item.name) {
if (props.theme === 'light') {
return 'c-nav-item_active';
} else if (props.theme === 'dark2') {
return 'c-nav-item-_active_dark2';
} else {
return 'c-nav-item_active_dark';
}
......@@ -114,6 +116,8 @@ export default defineComponent({
const getDefaultClass = (item: any) => {
if (props.theme === 'light') {
return 'c-nav-item-light';
} else if (props.theme === 'dark2') {
return 'c-nav-item-dark2';
} else {
return 'c-nav-item-dark';
}
......@@ -136,9 +140,7 @@ export default defineComponent({
<div class="c-tabs__nav-item-wrapper">{item.label}</div>
</div>
))}
{props.theme === 'light' ? (
''
) : (
{props.theme === 'dark' ? (
<div
class="c-tabs__bar"
style={{
......@@ -147,6 +149,8 @@ export default defineComponent({
right: tab_bar.right + 'px',
}}
></div>
) : (
''
)}
</div>
<div class="c-tabs-content">{slots.default?.()}</div>
......
......@@ -25,4 +25,7 @@
background: rgb(48, 48, 48);
}
}
.izable-page-tabs {
margin-top: 50px;
}
}
......@@ -9,7 +9,7 @@ export default defineComponent({
label: String,
uploadInfo: Object as any,
},
setup(props) {
setup(props, { slots }) {
return () => (
<div class="custom-izable-page">
<div class="header">
......@@ -23,6 +23,7 @@ export default defineComponent({
<Button theme="green">生成</Button>
</div>
</div>
<div class="izable-page-tabs">{slots.default?.()}</div>
</div>
);
},
......
<template>
<div class="custom-card-box" @click="onChange" :class="[clicked ? 'cursor-pointer' : '', className]">
<div class="img-box" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
<img :src="img" alt="" />
<div v-show="showHover">
<slot name="hover"></slot>
</div>
</div>
<div>
<template v-if="edit">
<ChangeName :value="value" @change="nameChange"></ChangeName>
</template>
<template v-else>
{{ name }}
</template>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import ChangeName from './changeName.vue';
const props = withDefaults(
defineProps<{
id: string | number;
......@@ -16,19 +29,44 @@ const props = withDefaults(
clicked?: boolean;
className?: string;
row?: any;
edit?: boolean;
}>(),
{
clicked: true,
customLast: true,
className: '',
row: {},
edit: false,
},
);
const emit = defineEmits(['change']);
const emit = defineEmits(['change', 'nameChange']);
const value = ref(props.name);
// hover内容是否显示
const showHover = ref(false);
const nameChange = (name: string) => {
emit('nameChange', props.id, name);
};
const onChange = () => {
props.clicked && emit('change', props.id, props.row);
};
const handleMouseEnter = () => {
showHover.value = true;
};
const handleMouseLeave = () => {
showHover.value = false;
};
watch(
() => props.name,
(v) => {
value.value = v;
},
);
</script>
<style lang="less">
......@@ -36,19 +74,23 @@ const onChange = () => {
.custom-card-box {
width: 170px;
height: 224px;
background: #fff;
background: #1e1e1e;
border-radius: 8px;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
padding: 12px;
text-align: center;
font-size: @size-16;
box-sizing: border-box;
color: white;
.img-box {
position: relative;
img {
width: 100%;
height: 174px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
}
}
.cursor-pointer {
cursor: pointer;
......
......@@ -61,7 +61,7 @@ const handleMouseLeave = () => {
.custom-card-two-box {
width: 200px;
height: 310px;
background: #fff;
background: #1e1e1e;
border-radius: 8px;
transition: all 0.2s;
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.3);
......
......@@ -70,7 +70,7 @@ watch(
<style lang="less">
@import '@/style/variables.less';
.custom-change-name-box {
color: @main-color;
color: white;
font-size: @size-16;
display: flex;
justify-content: space-between;
......
......@@ -79,6 +79,12 @@ export const getRoutes = () => {
component: () => import('@/pages/ImageCustomization/index.vue'),
meta: { title: 'snowhome' },
},
{
path: routerConfig.VocalCustomization.path,
name: routerConfig.VocalCustomization.name,
component: () => import('@/pages/VocalCustomization/index.vue'),
meta: { title: 'snowhome' },
},
];
}
};
......
<template>
<div class="s-header">
<div class="logo">猫眼数字人</div>
<div class="logo" @click="goHome">
<img :src="imgs.logo" alt="" />
</div>
<div class="s-header-live-name" v-if="route.meta.liveName">
<ChangeName :value="liveName" :event="liveNameEvent"></ChangeName>
</div>
......@@ -23,6 +25,10 @@ const route = useRoute();
const router = useRouter();
const store = useStore();
const routeQuery = route.query;
const imgs = {
logo: new URL('../../assets/svg/logo.svg', import.meta.url).href,
};
// 获取标题
const liveName = computed(() => store.getters['live/getName']);
......@@ -30,6 +36,12 @@ onMounted(() => {
store.commit('live/setName', routeQuery.title ? routeQuery.title : '');
});
const goHome = () => {
router.replace({
path: '/',
});
};
const liveNameEvent = async (value: string) => {
router.replace({
path: routerConfig.createLive.path,
......@@ -52,14 +64,16 @@ const liveNameEvent = async (value: string) => {
position: sticky;
top: 0;
z-index: 100;
background: #ffffff;
background: #303030;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
.logo {
font-weight: 700;
font-size: 24px;
cursor: pointer;
img {
width: 60px;
}
}
.s-header-live-name {
.custom-change-name-box {
......
<template>
<div class="image-custom-my-person-box">
<div class="my-person-items">
<template v-for="item in personList.list" :key="item.id">
<template v-if="item.status">
<CardOne :id="item.id" :img="item.img" :name="item.name" :edit="true" @nameChange="nameChange">
<template #hover>
<div class="my-digtal-people-hover2">
<template v-if="true">
<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>
</template>
<div class="digtal-people-hover-tool">
<Button size="13" theme="dark" @click="openDialog(item)">删除</Button>
</div>
</div>
</template>
</CardOne>
</template>
<template v-else>
<div class="my-person-loading-item">
<Loading></Loading>
</div>
</template>
</template>
</div>
<ConfirmDialog v-model="confirmDialog" title="确认删除吗?" @confirm="confirm"></ConfirmDialog>
</div>
</template>
<script lang="ts" setup>
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import Button from '@/components/Button.vue';
import Loading from '@/components/loading.vue';
import CardOne from '@/components/cardOne.vue';
import { createTestData } from '@/utils/tool';
import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import routerConfig from '@/router/tool';
const router = useRouter();
const personList = reactive({
list: [],
});
const confirmDialog = ref(false);
const deleteId = ref();
const openDialog = (item: any) => {
confirmDialog.value = true;
deleteId.value = item.id;
};
// 修改名称
const nameChange = (id: number | string, name: string) => {};
// 确认删除
const confirm = () => {
//
};
// 获取我的数字人列表
const getList = () => {
try {
personList.list = createTestData({
img: ' https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: true,
});
personList.list.unshift({
img: ' https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: false,
});
} catch (e) {
console.log(e);
}
};
const startLive = (item: any) => {
router.push({
path: routerConfig.createLive.path,
name: routerConfig.createLive.name,
query: {
id: item.id,
title: '',
},
});
};
onMounted(() => {
getList();
});
</script>
<style lang="less">
@import '@/style/variables';
.image-custom-my-person-box {
padding: 30px 40px;
border-radius: 4px 4px 0px 0px;
background: #303030;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.04);
.my-person-items {
display: flex;
justify-content: space-between;
row-gap: 20px;
flex-wrap: wrap;
.custom-change-name-box {
justify-content: center;
}
.my-digtal-people-hover2 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0 12px;
display: flex;
flex-direction: column;
.digtal-people-start-end {
margin-top: 60px;
}
.digtal-people-hover-tool {
flex: 1;
.dja();
margin-bottom: 20px;
}
}
.my-person-loading-item {
border-radius: 8px;
background: #1e1e1e;
width: 170px;
height: 224px;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
position: relative;
}
}
}
</style>
<template>
<div class="image-custom-record">
<div class="record-items" v-for="item in recordList.list" :key="item.id">
<div class="left">
<img :src="item.img" alt="" />
</div>
<div class="center">
<div class="name">
名称:
<span>{{ item.name }}</span>
</div>
<div class="create">
创建时间:
<span>{{ item.created_at }}</span>
</div>
</div>
<div class="right">
<template v-if="item.status == 1">
<div class="status">
<img :src="imgs.underReview" />
<div>审核中</div>
</div>
</template>
<template v-else-if="item.status == 2">
<div class="status">
<img :src="imgs.auditFailure" />
<div>审核失败</div>
</div>
</template>
<template v-else-if="item.status == 3">
<div class="status">
<img :src="imgs.progress" />
<div>进行中</div>
</div>
</template>
<template v-else-if="item.status == 4">
<div class="status">
<img :src="imgs.success" />
<div>已完成</div>
</div>
</template>
</div>
</div>
</div>
</template>
<script lang="tsx" setup>
import { createTestData } from '@/utils/tool';
import { onMounted, reactive, ref } from 'vue';
const imgs = {
underReview: new URL('../../../assets/svg/custom/underReview.svg', import.meta.url).href,
auditFailure: new URL('../../../assets/svg/custom/auditFailure.svg', import.meta.url).href,
progress: new URL('../../../assets/svg/custom/progress.svg', import.meta.url).href,
success: new URL('../../../assets/svg/custom/success.svg', import.meta.url).href,
};
const recordList = reactive({
list: [],
});
const loading = ref(false);
const getList = () => {
try {
recordList.list = createTestData(
{
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 1,
created_at: '2023-7-10 15:57',
},
2,
);
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 2,
created_at: '2023-7-10 15:57',
});
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 3,
created_at: '2023-7-10 15:57',
});
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 4,
created_at: '2023-7-10 15:57',
});
} catch (e) {
console.log(e);
}
};
onMounted(() => {
getList();
});
</script>
<style lang="less">
@import '@/style/variables.less';
.image-custom-record {
border-radius: 0px 6px 0px 0px;
background: #303030;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.04);
min-height: 200px;
padding: 20px;
& > :not(:first-child) {
margin-top: 12px;
}
.record-items {
border-radius: 6px;
background: #1e1e1e;
height: 150px;
display: flex;
align-items: center;
padding: 0 60px;
.left {
width: 250px;
height: 120px;
img {
border-radius: 8px;
width: 200px;
height: 100%;
}
}
.center {
flex: 1;
color: #fff;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
.name {
font-size: @size-18;
}
.create {
font-size: @size-16;
}
}
.right {
.status {
font-size: @size-18;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
}
}
</style>
<template>
<div class="">
<Customizable :icon="getIcon()" :uploadInfo="uploadInfo" :label="'形象定制'"></Customizable>
<Customizable :icon="getIcon()" :uploadInfo="uploadInfo" :label="'形象定制'">
<CustomTabs v-model="currentTab" theme="dark2">
<CustomTabPanel name="1" label="我的数字人">
<MyDigitalPerson></MyDigitalPerson>
</CustomTabPanel>
<CustomTabPanel name="2" label="生成记录">
<Record></Record>
</CustomTabPanel>
</CustomTabs>
</Customizable>
</div>
</template>
<script lang="tsx" setup>
import Record from './components/Record.vue';
import MyDigitalPerson from './components/MyDigitalPerson.vue';
import CustomTabs from '@/components/CustomTabs';
import CustomTabPanel from '@/components/CustomTabPanel';
import Customizable from '@/components/Customizable';
import PersonSvg from '@/assets/svg/custom/person.svg';
import UploadSuccessIcon from '@/assets/svg/upload/video.svg';
import { ref } from 'vue';
const currentTab = ref('1');
const getIcon = () => {
return <PersonSvg></PersonSvg>;
......
<template>
<div class="image-custom-my-person-box">
<div class="my-person-items">
<template v-for="item in personList.list" :key="item.id">
<template v-if="item.status">
<div class="my-person-loading-item">
<Audio :url="item.url" mode="2" :clickPlay="true"></Audio>
<ChangeName :value="item.name"></ChangeName>
</div>
</template>
<template v-else>
<div class="my-person-loading-item">
<Loading></Loading>
</div>
</template>
</template>
</div>
<ConfirmDialog v-model="confirmDialog" title="确认删除吗?" @confirm="confirm"></ConfirmDialog>
</div>
</template>
<script lang="ts" setup>
import ChangeName from '@/components/changeName.vue';
import Audio from '@/components/Audio.vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import Button from '@/components/Button.vue';
import Loading from '@/components/loading.vue';
import CardOne from '@/components/cardOne.vue';
import { createTestData } from '@/utils/tool';
import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import routerConfig from '@/router/tool';
const router = useRouter();
const personList = reactive({
list: [],
});
const confirmDialog = ref(false);
const deleteId = ref();
const openDialog = (item: any) => {
confirmDialog.value = true;
deleteId.value = item.id;
};
// 修改名称
const nameChange = (id: number | string, name: string) => {};
// 确认删除
const confirm = () => {
//
};
// 获取我的数字人列表
const getList = () => {
try {
personList.list = createTestData({
img: ' https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: true,
url: '',
});
personList.list.unshift({
img: ' https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: false,
url: '',
});
} catch (e) {
console.log(e);
}
};
const startLive = (item: any) => {
router.push({
path: routerConfig.createLive.path,
name: routerConfig.createLive.name,
query: {
id: item.id,
title: '',
},
});
};
onMounted(() => {
getList();
});
</script>
<style lang="less">
@import '@/style/variables';
.image-custom-my-person-box {
padding: 30px 40px;
border-radius: 4px 4px 0px 0px;
background: #303030;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.04);
.my-person-items {
display: flex;
justify-content: space-between;
row-gap: 20px;
flex-wrap: wrap;
.custom-change-name-box {
justify-content: center;
}
.my-digtal-people-hover2 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0 12px;
display: flex;
flex-direction: column;
.digtal-people-start-end {
margin-top: 60px;
}
.digtal-people-hover-tool {
flex: 1;
.dja();
margin-bottom: 20px;
}
}
.my-person-loading-item {
border-radius: 8px;
background: #1e1e1e;
width: 170px;
height: 224px;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
position: relative;
.mode-2-audio {
margin: 50px 0;
& > :last-child {
margin-top: 20px;
}
}
.custom-change-name-box {
color: white;
}
}
}
}
</style>
<template>
<div class="image-custom-record">
<div class="record-items" v-for="item in recordList.list" :key="item.id">
<div class="left">
<Audio :url="item.url" mode="3"></Audio>
</div>
<div class="center">
<div class="name">
名称:
<span>{{ item.name }}</span>
</div>
<div class="create">
创建时间:
<span>{{ item.created_at }}</span>
</div>
</div>
<div class="right">
<template v-if="item.status == 1">
<div class="status">
<img :src="imgs.underReview" />
<div>审核中</div>
</div>
</template>
<template v-else-if="item.status == 2">
<div class="status">
<img :src="imgs.auditFailure" />
<div>审核失败</div>
</div>
</template>
<template v-else-if="item.status == 3">
<div class="status">
<img :src="imgs.progress" />
<div>进行中</div>
</div>
</template>
<template v-else-if="item.status == 4">
<div class="status">
<img :src="imgs.success" />
<div>已完成</div>
</div>
</template>
</div>
</div>
</div>
</template>
<script lang="tsx" setup>
import Audio from '@/components/Audio.vue';
import { createTestData } from '@/utils/tool';
import { onMounted, reactive, ref } from 'vue';
const imgs = {
underReview: new URL('../../../assets/svg/custom/underReview.svg', import.meta.url).href,
auditFailure: new URL('../../../assets/svg/custom/auditFailure.svg', import.meta.url).href,
progress: new URL('../../../assets/svg/custom/progress.svg', import.meta.url).href,
success: new URL('../../../assets/svg/custom/success.svg', import.meta.url).href,
};
const recordList = reactive({
list: [],
});
const loading = ref(false);
const getList = () => {
try {
recordList.list = createTestData(
{
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 1,
url: '',
created_at: '2023-7-10 15:57',
},
2,
);
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 2,
url: '',
created_at: '2023-7-10 15:57',
});
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 3,
url: '',
created_at: '2023-7-10 15:57',
});
recordList.list.unshift({
img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwRTUox_S_qSFas_3lp-8Z00Las63sh2W6ORvmWgHw&s',
name: '夏青',
status: 4,
url: '',
created_at: '2023-7-10 15:57',
});
} catch (e) {
console.log(e);
}
};
onMounted(() => {
getList();
});
</script>
<style lang="less">
@import '@/style/variables.less';
.image-custom-record {
border-radius: 0px 6px 0px 0px;
background: #303030;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.04);
min-height: 200px;
padding: 20px;
& > :not(:first-child) {
margin-top: 12px;
}
.record-items {
border-radius: 6px;
background: #1e1e1e;
height: 150px;
display: flex;
align-items: center;
padding: 0 60px;
.left {
width: 150px;
height: 120px;
.dja(flex-start);
img {
border-radius: 8px;
width: 200px;
height: 100%;
}
}
.center {
flex: 1;
color: #fff;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
.name {
font-size: @size-18;
}
.create {
font-size: @size-16;
}
}
.right {
.status {
font-size: @size-18;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
}
}
</style>
<template>
<div class="">
<Customizable :icon="getIcon()" :uploadInfo="uploadInfo" :label="'声音定制'">
<CustomTabs v-model="currentTab" theme="dark2">
<CustomTabPanel name="1" label="我的音色">
<MyDigitalPerson></MyDigitalPerson>
</CustomTabPanel>
<CustomTabPanel name="2" label="生成记录">
<Record></Record>
</CustomTabPanel>
</CustomTabs>
</Customizable>
</div>
</template>
<script lang="tsx" setup>
import Record from './components/Record.vue';
import MyDigitalPerson from './components/MyDigitalPerson.vue';
import CustomTabs from '@/components/CustomTabs';
import CustomTabPanel from '@/components/CustomTabPanel';
import Customizable from '@/components/Customizable';
import PersonSvg from '@/assets/svg/custom/audit.svg';
import UploadSuccessIcon from '@/assets/svg/upload/video.svg';
import { ref } from 'vue';
const imgs = {
speak: new URL('../../assets/img/speaking.png', import.meta.url).href,
};
const currentTab = ref('1');
const getIcon = () => {
return <img src={imgs.speak} style="" />;
};
const uploadInfo = {
label1: '选择音频',
label2: '或拖音频到此处上传',
buttonLabel: '选择音频',
successIcon: <UploadSuccessIcon></UploadSuccessIcon>,
successButtonLabel: '替换音频',
};
</script>
<style lang="less"></style>
......@@ -51,7 +51,7 @@ const myDigtalList = reactive({
<style lang="less">
.digital-people-draft {
padding: 20px 30px;
background: white;
background: #303030;
position: relative;
min-height: 300px;
.card-item-list {
......
......@@ -70,7 +70,7 @@ const startLive = (item: any) => {
<style lang="less">
.my-digtal-people {
padding: 20px 30px;
background: white;
background: #303030;
position: relative;
min-height: 300px;
.card-item-list {
......
......@@ -34,7 +34,7 @@
</div>
</div>
<div class="home-tool-bar">
<CustomTabs v-model="currentTab">
<CustomTabs v-model="currentTab" theme="dark2">
<CustomTabPanel label="数字人作品" name="1"> <MyDigtalPeople></MyDigtalPeople> </CustomTabPanel>
<CustomTabPanel label="数字人草稿" name="2"> <DigitalPeopleDraft></DigitalPeopleDraft> </CustomTabPanel>
</CustomTabs>
......@@ -84,11 +84,12 @@ const toolList = [
{
label: '形象定制',
icon: imgs.profile,
path: routerConfig.ImageCustomization,
path: routerConfig.ImageCustomization.path,
},
{
label: '音色定制',
icon: imgs.speaking,
path: routerConfig.VocalCustomization.path,
},
{
label: '互动回答',
......@@ -99,8 +100,7 @@ const toolList = [
const openPage = (item: any) => {
if (item.path) {
router.push({
path: routerConfig.ImageCustomization.path,
name: routerConfig.ImageCustomization.name,
path: item.path,
});
}
};
......@@ -169,10 +169,11 @@ const dialogConfirm = () => {
width: 100%;
border-radius: 6px;
height: 85px;
background: white;
background: #303030;
display: flex;
align-items: center;
padding: 0 20px;
color: rgba(180, 180, 180, 0.9);
& > :not(:first-child) {
margin-left: 40px;
}
......@@ -190,7 +191,7 @@ const dialogConfirm = () => {
margin-top: 12px;
width: 100%;
height: 348px;
background: white;
background: #303030;
padding: 33px 30px 0px 30px;
border-radius: 6px;
.tool-line {
......@@ -200,6 +201,7 @@ const dialogConfirm = () => {
.label {
font-size: @size-20;
font-weight: 400;
color: #b4b4b4;
}
}
.digital-people-list {
......@@ -212,7 +214,7 @@ const dialogConfirm = () => {
.more-choices {
width: 170px;
height: 224px;
background: #fff;
background: #1e1e1e;
border-radius: 8px;
transition: all 0.2s;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
......
......@@ -62,6 +62,7 @@ import { computed, onMounted, reactive, ref } from 'vue';
import { show_message } from '@/utils/tool';
import { useStore } from 'vuex';
import { setRememberList, getRememberList } from '@/utils/remember';
import { UserLogin } from '@/utils/api/userApi';
const store = useStore();
const loading = ref(false);
......
......@@ -30,4 +30,8 @@ export default {
path: '/ImageCustomization',
name: 'ImageCustomization',
},
VocalCustomization: {
path: '/VocalCustomization',
name: 'VocalCustomization',
},
};
......@@ -9,11 +9,9 @@ export const getLanguage = () => {
return store.getters['language/getLang'];
};
// 获取邮箱注册验证码
export const getVerificationCode = (data: any) => {
return request.post('/api/users/register-code', {
...data,
});
// 登录
export const UserLogin = (data: any) => {
return request.post('/api/login', data);
};
// 用户余额
......
......@@ -9,7 +9,7 @@ const mode = import.meta.env.MODE;
const getBaseUrl = () => {
if (mode == 'development') {
//
return 'http://43.138.133.103:85';
return '';
}
return 'http://43.138.133.103:85';
};
......
......@@ -16,6 +16,7 @@ import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig(({ command, mode }) => {
// https://m.coinwg.com 测试服务器
// https://tidrk.com/
let api = 'http://video-assistant.test';
return {
base: './',
resolve: {
......@@ -65,7 +66,7 @@ export default defineConfig(({ command, mode }) => {
port: 3010,
host: '0.0.0.0',
proxy: {
// '/api': api,
'/api': api,
},
},
build: {
......
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