feat: 视频生成优化生成中ui
This commit is contained in:
parent
e1bcc4c13f
commit
c3ea81e69f
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "digital-news-live",
|
"name": "ai-live",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "数字人直播间",
|
"description": "数字人直播间",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -2,6 +2,8 @@ import AppRouter from "@/routes";
|
|||||||
import {ConfigProvider} from "@/contexts/config";
|
import {ConfigProvider} from "@/contexts/config";
|
||||||
import {AuthProvider} from "@/contexts/auth";
|
import {AuthProvider} from "@/contexts/auth";
|
||||||
|
|
||||||
|
console.log(`APP-BUILD-AT: ${AppBuildVersion}`)
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<ConfigProvider>
|
<ConfigProvider>
|
||||||
|
@ -49,26 +49,20 @@ export const VideoListItem = (
|
|||||||
{/* <div className="index-value w-[40px] h-[40px] flex items-center justify-center bg-gray-100 rounded-3xl">{index}</div>*/}
|
{/* <div className="index-value w-[40px] h-[40px] flex items-center justify-center bg-gray-100 rounded-3xl">{index}</div>*/}
|
||||||
{/*</div>}*/}
|
{/*</div>}*/}
|
||||||
<div
|
<div
|
||||||
className={`video-item-info flex gap-2 flex-1 bg-gray-100 h-[80px] overflow-hidden rounded-lg p-3 shadow-blue-500 ${active ? 'video-item-shadow' : ''}`}>
|
className={`video-item-info relative flex gap-2 flex-1 bg-gray-100 h-[80px] overflow-hidden rounded-lg p-3 shadow-blue-500 ${active ? 'video-item-shadow' : ''}`}>
|
||||||
<div className={'video-title leading-7 flex-1'}>{video.title || video.video_title}</div>
|
<div className={'video-title leading-7 flex-1'}>{video.title || video.video_title}</div>
|
||||||
<div className={'video-item-cover bg-white rounded-md overflow-hidden'}>
|
<div className={'video-item-cover bg-white rounded-md overflow-hidden'}>
|
||||||
<img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover} />
|
<img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover} />
|
||||||
</div>
|
</div>
|
||||||
|
{type == 'create' && video.status == VideoStatus.Generating && <div className={'absolute inset-0 bg-black/30 text-white flex items-center justify-center'}>
|
||||||
|
<span className="ml-1">视频生成中</span>
|
||||||
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className="operation flex items-center ml-2 gap-3 text-lg text-gray-400">
|
<div className="operation flex items-center ml-2 gap-3 text-lg text-gray-400 w-[116px]">
|
||||||
{sortable && (!active ? <button className="hover:text-blue-500 cursor-move" {...attributes} {...listeners}>
|
{sortable && (!active ? <button className="hover:text-blue-500 cursor-move" {...attributes} {...listeners}>
|
||||||
<MenuOutlined/>
|
<MenuOutlined/>
|
||||||
</button> : <button disabled className="cursor-not-allowed"><MenuOutlined/></button>)}
|
</button> : <button disabled className="cursor-not-allowed"><MenuOutlined/></button>)}
|
||||||
{onPlay &&
|
{onPlay &&<button className="hover:text-blue-500" onClick={onPlay} style={{fontSize: '1.3em'}}><IconPlay/></button>}
|
||||||
<>
|
|
||||||
{(
|
|
||||||
type == 'create' && video.status == VideoStatus.Generating
|
|
||||||
) ? <button title="视频生成中" className="flex items-center justify-center">
|
|
||||||
<LoadingOutlined className="block text-gray-500" style={{fontSize: '0.85em'}}/>
|
|
||||||
</button>: <button className="hover:text-blue-500" onClick={onPlay} style={{fontSize: '1.3em'}}><IconPlay/>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</>}
|
|
||||||
|
|
||||||
{editable && <>
|
{editable && <>
|
||||||
{onEdit &&
|
{onEdit &&
|
||||||
|
@ -50,7 +50,7 @@ export default function NewsIndex() {
|
|||||||
<SearchPanel onSearch={setParams}/>
|
<SearchPanel onSearch={setParams}/>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="news-list-container">
|
<Card className="news-list-container">
|
||||||
<Modal open={!!activeNews} width={1000} footer={null} onCancel={() => setActiveNews(undefined)}>
|
{activeNews && <Modal open={true} width={1000} footer={null} onCancel={() => setActiveNews(undefined)}>
|
||||||
<div className="news-detail px-3 pb-5">
|
<div className="news-detail px-3 pb-5">
|
||||||
<div className="new-title text-2xl">{activeNews?.title}</div>
|
<div className="new-title text-2xl">{activeNews?.title}</div>
|
||||||
<div className="info mt-2 mb-5 text-sm flex gap-3">
|
<div className="info mt-2 mb-5 text-sm flex gap-3">
|
||||||
@ -60,7 +60,7 @@ export default function NewsIndex() {
|
|||||||
<div className="overflow-auto leading-7 text-base"
|
<div className="overflow-auto leading-7 text-base"
|
||||||
style={{maxHeight: 1000}} dangerouslySetInnerHTML={{__html: activeNews?.content || ''}}></div>
|
style={{maxHeight: 1000}} dangerouslySetInnerHTML={{__html: activeNews?.content || ''}}></div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>}
|
||||||
<div className="controls flex justify-between mb-1">
|
<div className="controls flex justify-between mb-1">
|
||||||
<div>
|
<div>
|
||||||
<Checkbox checked={state.checkAll} onChange={e => {
|
<Checkbox checked={state.checkAll} onChange={e => {
|
||||||
@ -90,7 +90,7 @@ export default function NewsIndex() {
|
|||||||
}
|
}
|
||||||
}}/>
|
}}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="news-content">
|
<div className="news-content flex-1">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="title text-lg cursor-pointer" onClick={() => {
|
<div className="title text-lg cursor-pointer" onClick={() => {
|
||||||
handleViewNewsDetail(item.id)
|
handleViewNewsDetail(item.id)
|
||||||
|
@ -4,13 +4,14 @@ import {showErrorToast, showToast} from "@/components/message.ts";
|
|||||||
import {push2room, VideoStatus} from "@/service/api/video.ts";
|
import {push2room, VideoStatus} from "@/service/api/video.ts";
|
||||||
|
|
||||||
|
|
||||||
export default function ButtonPush2Room(props: { ids: Id[]; list: VideoInfo[] }) {
|
export default function ButtonPush2Room(props: { ids: Id[]; list: VideoInfo[];onSuccess?:()=>void; }) {
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const handlePush = () => {
|
const handlePush = () => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
// 只需要已经生成视频的数据id
|
// 只需要已经生成视频的数据id
|
||||||
const vids = props.list.filter(v => v.status == VideoStatus.Generated && props.ids.includes(v.id)).map(v => v.id)
|
const vids = props.list.filter(v => v.status == VideoStatus.Generated && props.ids.includes(v.id)).map(v => v.id)
|
||||||
push2room(vids).then(() => {
|
push2room(vids).then(() => {
|
||||||
|
props.onSuccess?.()
|
||||||
if(props.ids.length == vids.length){
|
if(props.ids.length == vids.length){
|
||||||
showToast('一键推流成功,已推流至数字人直播间,请前往数字人直播间页面查看!', 'success')
|
showToast('一键推流成功,已推流至数字人直播间,请前往数字人直播间页面查看!', 'success')
|
||||||
}else{
|
}else{
|
||||||
|
@ -150,12 +150,12 @@ export default function VideoIndex() {
|
|||||||
return newArr;
|
return newArr;
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
onPlay={() => playVideo(v, index)}
|
onPlay={v.status == VideoStatus.Generating ? undefined :() => playVideo(v, index)}
|
||||||
onEdit={() => {
|
onEdit={v.status == VideoStatus.Generating ? undefined : () => {
|
||||||
setEditId(v.article_id)
|
setEditId(v.article_id)
|
||||||
}}
|
}}
|
||||||
editable={true}
|
editable={v.status != VideoStatus.Generating}
|
||||||
sortable={true}
|
sortable={v.status != VideoStatus.Generating}
|
||||||
/>))}
|
/>))}
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
@ -172,13 +172,13 @@ export default function VideoIndex() {
|
|||||||
{/* confirmMessage={`是否确定一键推流选中新闻视频?`}*/}
|
{/* confirmMessage={`是否确定一键推流选中新闻视频?`}*/}
|
||||||
{/* onSuccess={loadList}*/}
|
{/* onSuccess={loadList}*/}
|
||||||
{/*>一键推流</ButtonBatch>*/}
|
{/*>一键推流</ButtonBatch>*/}
|
||||||
<ButtonPush2Room ids={checkedIdArray} list={videoData}/>
|
<ButtonPush2Room ids={checkedIdArray} list={videoData} onSuccess={loadList}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="video-player-container ml-16 w-[360px] flex flex-col">
|
<div className="video-player-container ml-16 w-[360px] flex flex-col">
|
||||||
<div className="text-center text-base">预览视频</div>
|
<div className="text-center text-base">预览视频</div>
|
||||||
<div className="video-player flex items-center mt-2">
|
<div className="video-player flex items-center mt-2">
|
||||||
<div className=" w-[360px] h-[640px] rounded overflow-hidden">
|
<div className=" w-[360px] h-[630px] rounded overflow-hidden">
|
||||||
{/*<video ref={videoRef} poster={videoData[state.playingIndex]?.cover} preload="auto" playsinline webkit-playsinline className="w-full bg-white w-[360px] h-[640px]"></video>*/}
|
{/*<video ref={videoRef} poster={videoData[state.playingIndex]?.cover} preload="auto" playsinline webkit-playsinline className="w-full bg-white w-[360px] h-[640px]"></video>*/}
|
||||||
<Player
|
<Player
|
||||||
ref={player} url={videoData[state.playingIndex]?.oss_video_url}
|
ref={player} url={videoData[state.playingIndex]?.oss_video_url}
|
||||||
|
1
src/vite-env.d.ts
vendored
1
src/vite-env.d.ts
vendored
@ -5,6 +5,7 @@ declare type decimal = number;
|
|||||||
declare type int = number;
|
declare type int = number;
|
||||||
declare type AllType = string | number | object | undefined | null;
|
declare type AllType = string | number | object | undefined | null;
|
||||||
declare const APP_SITE_URL: string;
|
declare const APP_SITE_URL: string;
|
||||||
|
declare const AppBuildVersion: string;
|
||||||
declare const AppConfig: {
|
declare const AppConfig: {
|
||||||
// 登录凭证 token key
|
// 登录凭证 token key
|
||||||
AUTH_TOKEN_KEY: string;
|
AUTH_TOKEN_KEY: string;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import {defineConfig} from 'vite'
|
import {defineConfig} from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import {resolve} from "path";
|
import {resolve} from "path";
|
||||||
|
import AppPackage from './package.json'
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({mode}) => {
|
export default defineConfig(({mode}) => {
|
||||||
@ -8,7 +10,7 @@ export default defineConfig(({mode}) => {
|
|||||||
const AUTH_TOKEN_KEY = mode == 'production' ? 'digital-person-token' : `digital-person-token_${mode}`
|
const AUTH_TOKEN_KEY = mode == 'production' ? 'digital-person-token' : `digital-person-token_${mode}`
|
||||||
|
|
||||||
if (mode !== 'production') {
|
if (mode !== 'production') {
|
||||||
console.log('dev server is', devServerHost,mode)
|
console.log('dev server is', devServerHost, mode)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
@ -20,7 +22,8 @@ export default defineConfig(({mode}) => {
|
|||||||
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || AUTH_TOKEN_KEY,
|
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || AUTH_TOKEN_KEY,
|
||||||
AUTHED_PERSON_DATA_KEY: process.env.AUTHED_PERSON_DATA_KEY || 'digital-person-user-info',
|
AUTHED_PERSON_DATA_KEY: process.env.AUTHED_PERSON_DATA_KEY || 'digital-person-user-info',
|
||||||
}),
|
}),
|
||||||
AppMode: JSON.stringify(mode)
|
AppMode: JSON.stringify(mode),
|
||||||
|
AppBuildVersion: JSON.stringify(AppPackage.name + '-' + AppPackage.version + '-' + dayjs().format('YYYYMMDDHH_mmss'))
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user