feat: ✨️ 新增新闻热点功能,支持手动/自动填充热点内容并完善相关验证逻辑
This commit is contained in:
parent
de7088f642
commit
e61bfcc26c
61
src/components/article/HotNews.tsx
Normal file
61
src/components/article/HotNews.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import styles from './article.module.scss'
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {Input, Switch} from "antd";
|
||||||
|
import {useMemo} from "react";
|
||||||
|
|
||||||
|
type HotNewsProps = {
|
||||||
|
news: string[];
|
||||||
|
mode: string;
|
||||||
|
onValueChange: (values: {
|
||||||
|
news: string[],
|
||||||
|
mode: string
|
||||||
|
}) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function HotNews({news, mode, onValueChange}: HotNewsProps) {
|
||||||
|
const {t,i18n} = useTranslation()
|
||||||
|
const demoPlaceholderList = useMemo(()=>{
|
||||||
|
return i18n.language == 'zh-CN' ? [
|
||||||
|
'例:韩正会见英国汇丰集团主席',
|
||||||
|
'例: 丁薛祥出席全国高校毕业生等青年就业创业工作视频...',
|
||||||
|
'例:俄称乌方再度袭击俄能源设施 乌称击退俄军进攻',
|
||||||
|
] : [
|
||||||
|
'please type hot news',
|
||||||
|
'please type hot news',
|
||||||
|
'please type hot news',
|
||||||
|
]
|
||||||
|
},[i18n.language])
|
||||||
|
const handleValueChange = (value: string, index: number) => {
|
||||||
|
const values = [...news]
|
||||||
|
values[index] = value
|
||||||
|
onValueChange({news: values, mode})
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={`${styles.hotNews} mt-3`}>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<div className="area-title">
|
||||||
|
<span className="title">{t("modal.hot_news.title")}</span>
|
||||||
|
</div>
|
||||||
|
<div className="mode">
|
||||||
|
<span className="mr-2">{mode == 'auto' ? t("modal.hot_news.edit_auto") : t("modal.hot_news.edit_manual")}</span>
|
||||||
|
<Switch size="small" checked={mode == 'auto'} onChange={checked => {
|
||||||
|
onValueChange({news, mode: checked ? 'auto' : 'manual'})
|
||||||
|
}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="hot-news-list panel-body p-3 ">
|
||||||
|
{news.map((item, index) => <div key={index} className={`hot-news-item bg-gray-50 ${index == 0?'':'mt-3'} rounded-xl`}>
|
||||||
|
<Input
|
||||||
|
variant={"borderless"}
|
||||||
|
readOnly={mode == 'auto'}
|
||||||
|
placeholder={mode != 'auto' ? demoPlaceholderList[index] : ''}
|
||||||
|
value={item}
|
||||||
|
onChange={e => handleValueChange(e.target.value, index)}/>
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HotNews
|
@ -46,7 +46,7 @@
|
|||||||
@apply flex gap-4;
|
@apply flex gap-4;
|
||||||
:global{
|
:global{
|
||||||
.area-title{
|
.area-title{
|
||||||
@apply text-gray-400 text-sm text-gray-800;
|
@apply text-gray-400 text-base text-gray-800;
|
||||||
}
|
}
|
||||||
.digital-person{
|
.digital-person{
|
||||||
width: 450px;
|
width: 450px;
|
||||||
@ -133,3 +133,9 @@
|
|||||||
.textarea {
|
.textarea {
|
||||||
@apply border-0
|
@apply border-0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hot news
|
||||||
|
.hotNews{
|
||||||
|
.title{}
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,15 @@
|
|||||||
import {Modal} from "antd";
|
import {Modal,App} from "antd";
|
||||||
import ArticleGroup from "@/components/article/group.tsx";
|
import React, {useEffect, useState} from "react";
|
||||||
import {useEffect, useState} from "react";
|
|
||||||
import {useSetState} from "ahooks";
|
import {useSetState} from "ahooks";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
import * as article from "@/service/api/article.ts";
|
import * as article from "@/service/api/article.ts";
|
||||||
import {regenerate} from "@/service/api/video.ts";
|
import {regenerate} from "@/service/api/video.ts";
|
||||||
import {push2video} from "@/service/api/article.ts";
|
import {push2video} from "@/service/api/article.ts";
|
||||||
import {showErrorToast, showToast} from "@/components/message.ts";
|
import {showErrorToast, showToast} from "@/components/message.ts";
|
||||||
import {useTranslation} from "react-i18next";
|
import ArticleGroup, {HotNewsData} from "@/components/article/group.tsx";
|
||||||
|
import type {HookAPI as ModalHookAPI} from "antd/es/modal/useModal";
|
||||||
|
import {TFunction} from "i18next";
|
||||||
|
import {IconWarningCircle} from "@/components/icons";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id?: number;
|
id?: number;
|
||||||
@ -70,7 +73,7 @@ function groupHasImageAndText(blocks: BlockContent[]) {
|
|||||||
function checkGroupsValid(_groups: BlockContent[][]) {
|
function checkGroupsValid(_groups: BlockContent[][]) {
|
||||||
const groups = _groups.filter((_,index)=>{
|
const groups = _groups.filter((_,index)=>{
|
||||||
if (index == 0) return true;
|
if (index == 0) return true;
|
||||||
return _.length>1;
|
return _.length > 1 || (_.length == 1 && _[0].content.trim().length > 0) ;
|
||||||
})
|
})
|
||||||
if (groups.length == 1) return true;
|
if (groups.length == 1) return true;
|
||||||
for (let index = 1;index< groups.length; index ++) {
|
for (let index = 1;index< groups.length; index ++) {
|
||||||
@ -78,19 +81,46 @@ function checkGroupsValid(_groups: BlockContent[][]) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
function checkHotNewsValid(hotNews: HotNewsData,modal:ModalHookAPI,t:TFunction<"translation", undefined>) {
|
||||||
|
return new Promise<boolean>((resolve)=>{
|
||||||
|
|
||||||
|
// 验证热点新闻数据是否正确
|
||||||
|
if(hotNews.mode == 'manual' && hotNews.list.filter(s=>s.trim().length > 0).length < 3){
|
||||||
|
modal.confirm({
|
||||||
|
wrapClassName: 'root-modal-confirm',
|
||||||
|
icon: <span className="anticon anticon-exclamation-circle"><IconWarningCircle/></span>,
|
||||||
|
title: t('modal.hot_news.empty_notice_title'),
|
||||||
|
content: t('modal.hot_news.empty_notice_message'),
|
||||||
|
centered:true,
|
||||||
|
onOk: () => {
|
||||||
|
resolve(true)
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default function ArticleEditModal(props: Props) {
|
export default function ArticleEditModal(props: Props) {
|
||||||
const {t} = useTranslation()
|
const {t} = useTranslation()
|
||||||
|
const {modal} = App.useApp()
|
||||||
const [groups, setGroups] = useState<BlockContent[][]>([]);
|
const [groups, setGroups] = useState<BlockContent[][]>([]);
|
||||||
const [title, setTitle] = useState('')
|
const [title, setTitle] = useState('')
|
||||||
|
const [hotNews,setHotNews] = useState<HotNewsData>({
|
||||||
|
list: ['','',''],
|
||||||
|
mode: 'auto'
|
||||||
|
})
|
||||||
const [state, setState] = useSetState({
|
const [state, setState] = useSetState({
|
||||||
...DEFAULT_STATE,
|
...DEFAULT_STATE,
|
||||||
generating:false
|
generating:false
|
||||||
})
|
})
|
||||||
|
|
||||||
// 保存数据
|
// 保存数据
|
||||||
const handleSave = () => {
|
const handleSave = async () => {
|
||||||
setState({error: ''})
|
setState({error: ''})
|
||||||
if (!title) {
|
if (!title) {
|
||||||
// setState({msgTitle: '请输入标题内容'});
|
// setState({msgTitle: '请输入标题内容'});
|
||||||
@ -106,13 +136,21 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
setState({msgGroup: t('news.edit_empty_group_content')});
|
setState({msgGroup: t('news.edit_empty_group_content')});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const hotNewsValid = await checkHotNewsValid(hotNews,modal,t)
|
||||||
|
if(!hotNewsValid) return;
|
||||||
// if (groups.length == 0 || groups[0].length == 0 || !groups[0][0].content) {
|
// if (groups.length == 0 || groups[0].length == 0 || !groups[0][0].content) {
|
||||||
// // setState({msgGroup: '请输入正文文本内容'});
|
// // setState({msgGroup: '请输入正文文本内容'});
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
const save = props.type == 'news' ? article.save : regenerate
|
const save = props.type == 'news' ? article.save : regenerate
|
||||||
setState({loading: true})
|
setState({loading: true})
|
||||||
save(title, groups[0][0].content, groups.slice(1), props.id && props.id > 0 ? props.id : undefined).then(() => {
|
save({
|
||||||
|
title,
|
||||||
|
metahuman_text: groups[0][0].content,
|
||||||
|
content_group: groups.slice(1),
|
||||||
|
hot_news: hotNews.list,
|
||||||
|
id: props.id && props.id > 0 ? props.id : undefined
|
||||||
|
}).then(() => {
|
||||||
props.onClose?.(true)
|
props.onClose?.(true)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
setState({error: e.message || t('news.edit_save_failed')})
|
setState({error: e.message || t('news.edit_save_failed')})
|
||||||
@ -121,6 +159,7 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const handlePush2Video = async () =>{
|
const handlePush2Video = async () =>{
|
||||||
|
//
|
||||||
if (!title) {
|
if (!title) {
|
||||||
// setState({msgTitle: '请输入标题内容'});
|
// setState({msgTitle: '请输入标题内容'});
|
||||||
return;
|
return;
|
||||||
@ -136,8 +175,16 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!props.id || state.generating) return;
|
if(!props.id || state.generating) return;
|
||||||
|
const hotNewsValid = await checkHotNewsValid(hotNews,modal,t)
|
||||||
|
if(!hotNewsValid) return;
|
||||||
setState({generating:true})
|
setState({generating:true})
|
||||||
await article.save(title, groups[0][0].content, groups.slice(1), props.id)
|
await article.save({
|
||||||
|
title,
|
||||||
|
metahuman_text: groups[0][0].content,
|
||||||
|
content_group: groups.slice(1),
|
||||||
|
hot_news: hotNews.list,
|
||||||
|
id: props.id,
|
||||||
|
})
|
||||||
push2video([props.id]).then(() => {
|
push2video([props.id]).then(() => {
|
||||||
showToast(t('news.push_stream_success'), 'success')
|
showToast(t('news.push_stream_success'), 'success')
|
||||||
// navigate('/create?state=push-success',{
|
// navigate('/create?state=push-success',{
|
||||||
@ -154,6 +201,13 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
// 如果传入了id则获取数据
|
// 如果传入了id则获取数据
|
||||||
if (props.id > 0) {
|
if (props.id > 0) {
|
||||||
article.getById(props.id).then(res => {
|
article.getById(props.id).then(res => {
|
||||||
|
const len = res.hot_news.length
|
||||||
|
const list = len >= 3 ? res.hot_news :res.hot_news.concat(Array(3 - len).fill(''))
|
||||||
|
console.log('list,',list,res.hot_news)
|
||||||
|
setHotNews({
|
||||||
|
list,
|
||||||
|
mode: res.hot_news_mode ?? 'auto'
|
||||||
|
})
|
||||||
setGroups(rebuildGroups([[{content: res.metahuman_text, type: "text"}], ...res.content_group]))
|
setGroups(rebuildGroups([[{content: res.metahuman_text, type: "text"}], ...res.content_group]))
|
||||||
setTitle(res.title)
|
setTitle(res.title)
|
||||||
})
|
})
|
||||||
@ -190,8 +244,12 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
<div className="article-body">
|
<div className="article-body">
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<ArticleGroup
|
<ArticleGroup
|
||||||
errorMessage={state.msgGroup} editable groups={groups}
|
errorMessage={state.msgGroup}
|
||||||
onChange={list => {
|
editable
|
||||||
|
groups={groups}
|
||||||
|
hotNews={hotNews}
|
||||||
|
onChange={(list,hotNews) => {
|
||||||
|
setHotNews(hotNews)
|
||||||
setGroups(() => list)
|
setGroups(() => list)
|
||||||
setState({msgGroup: (list.length == 0 || list[0].length == 0 || !list[0][0].content) ? t('news.edit_empty_human_content') : ''});
|
setState({msgGroup: (list.length == 0 || list[0].length == 0 || !list[0][0].content) ? t('news.edit_empty_human_content') : ''});
|
||||||
}}
|
}}
|
||||||
|
@ -6,16 +6,22 @@ import {showToast} from "@/components/message.ts";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {IconAdd} from "@/components/icons";
|
import {IconAdd} from "@/components/icons";
|
||||||
|
import HotNews from "@/components/article/HotNews.tsx";
|
||||||
|
|
||||||
|
export type HotNewsData = {
|
||||||
|
list: string[];
|
||||||
|
mode: string
|
||||||
|
}
|
||||||
type Props = {
|
type Props = {
|
||||||
groups: BlockContent[][];
|
groups: BlockContent[][];
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
onChange?: (groups: BlockContent[][]) => void;
|
onChange?: (groups: BlockContent[][], hotNews: HotNewsData) => void;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
|
hotNews: HotNewsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function ArticleGroup({groups, editable, onChange, errorMessage}: Props) {
|
export default function ArticleGroup({groups, editable, onChange, errorMessage, hotNews}: Props) {
|
||||||
const {t, i18n} = useTranslation()
|
const {t, i18n} = useTranslation()
|
||||||
// const groups = rebuildGroups(_groups)
|
// const groups = rebuildGroups(_groups)
|
||||||
/**
|
/**
|
||||||
@ -41,12 +47,12 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
} else {
|
} else {
|
||||||
_groups.splice(insertIndex, 0, newGroup)
|
_groups.splice(insertIndex, 0, newGroup)
|
||||||
}
|
}
|
||||||
onChange?.(_groups)
|
onChange?.(_groups, hotNews)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDigitalPersonContentChange = (content: string) => {
|
const handleDigitalPersonContentChange = (content: string) => {
|
||||||
groups[0] = [{type: 'text', content}]
|
groups[0] = [{type: 'text', content}]
|
||||||
onChange?.([...groups])
|
onChange?.([...groups], hotNews)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className={styles.group}>
|
return <div className={styles.group}>
|
||||||
@ -57,7 +63,8 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
</div>
|
</div>
|
||||||
<div className="panel-body p-3">
|
<div className="panel-body p-3">
|
||||||
{/* value={groups || groups[0][0].content}*/}
|
{/* value={groups || groups[0][0].content}*/}
|
||||||
<div className="h-[486px] pt-2 rounded-xl overflow-hidden bg-gray-50">
|
<div className="h-[306px] pt-2 rounded-xl overflow-hidden bg-gray-50">
|
||||||
|
<div className="human-tts">
|
||||||
{editable ? <div className="relative">
|
{editable ? <div className="relative">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
placeholder={t('news.edit_notice_enter_text')}
|
placeholder={t('news.edit_notice_enter_text')}
|
||||||
@ -72,6 +79,16 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="hot-news-container">
|
||||||
|
<HotNews
|
||||||
|
news={hotNews.list} mode={hotNews.mode}
|
||||||
|
onValueChange={(hotNews) => {
|
||||||
|
onChange?.([...groups], {
|
||||||
|
list:hotNews.news,mode: hotNews.mode
|
||||||
|
})
|
||||||
|
}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className={"panel groups-list flex-1"}>
|
<div className={"panel groups-list flex-1"}>
|
||||||
<div className={"area-title"}>
|
<div className={"area-title"}>
|
||||||
<span className="">{t('news.edit_other_text')}</span>
|
<span className="">{t('news.edit_other_text')}</span>
|
||||||
@ -81,9 +98,12 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
<div className="panel-body py-3">
|
<div className="panel-body py-3">
|
||||||
<div className="max-h-[485px] overflow-auto py-4">
|
<div className="max-h-[485px] overflow-auto py-4">
|
||||||
|
|
||||||
{editable && groups.length == 1 && <div className={`${styles.blockContainer} group`}><div className={'divider-container before'}><Divider>
|
{editable && groups.length == 1 && <div className={`${styles.blockContainer} group`}>
|
||||||
<span onClick={()=>handleAddGroup?.(1,1)} className="article-action-add" title={t('news.materials.add_group')}><IconAdd style={{fontSize: 24}}/></span>
|
<div className={'divider-container before'}><Divider>
|
||||||
</Divider></div></div> }
|
<span onClick={() => handleAddGroup?.(1, 1)} className="article-action-add"
|
||||||
|
title={t('news.materials.add_group')}><IconAdd style={{fontSize: 24}}/></span>
|
||||||
|
</Divider></div>
|
||||||
|
</div>}
|
||||||
|
|
||||||
{groups.map((g, index) => (
|
{groups.map((g, index) => (
|
||||||
index == 0 ? null : <ArticleBlock
|
index == 0 ? null : <ArticleBlock
|
||||||
@ -92,7 +112,7 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
blocks={g}
|
blocks={g}
|
||||||
onChange={(blocks) => {
|
onChange={(blocks) => {
|
||||||
groups[index] = blocks
|
groups[index] = blocks
|
||||||
onChange?.([...groups])
|
onChange?.([...groups], hotNews)
|
||||||
}}
|
}}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
index={index}
|
index={index}
|
||||||
@ -105,7 +125,7 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
message.warning(t('news.edit_notice_keep_1'))
|
message.warning(t('news.edit_notice_keep_1'))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onChange?.(groups.filter((_, idx) => index !== idx))
|
onChange?.(groups.filter((_, idx) => index !== idx), hotNews)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -113,7 +133,7 @@ export default function ArticleGroup({groups, editable, onChange, errorMessage}:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{groups.length == 0 && editable &&
|
{groups.length == 0 && editable &&
|
||||||
<ArticleBlock editable onChange={blocks => onChange?.([blocks])} index={0}
|
<ArticleBlock editable onChange={blocks => onChange?.([blocks],hotNews)} index={0}
|
||||||
blocks={[{type: 'text', content: ''}]}/>}
|
blocks={[{type: 'text', content: ''}]}/>}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
@ -1,14 +1,8 @@
|
|||||||
{
|
{
|
||||||
"AppTitle": "AI Livesteam",
|
"AppTitle": "AI Livesteam",
|
||||||
"go_to_home": "Go to Homepage" ,
|
|
||||||
"Hello": "Hello",
|
"Hello": "Hello",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"service_error": "Service exception, please contact customer support.",
|
|
||||||
"error_401": "You do not have permission to access this page",
|
|
||||||
"error_403": "You do not have permission to access this page",
|
|
||||||
"error_404": "Page not found",
|
|
||||||
"error_500": "Service exception, please contact customer support.",
|
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"push_title": "Push Notice",
|
"push_title": "Push Notice",
|
||||||
"push_video": "Are you sure editing selected news?",
|
"push_video": "Are you sure editing selected news?",
|
||||||
@ -20,9 +14,14 @@
|
|||||||
"delete_failed": "Delete failed",
|
"delete_failed": "Delete failed",
|
||||||
"delete_success": "Delete success",
|
"delete_success": "Delete success",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
|
"error_401": "You do not have permission to access this page",
|
||||||
|
"error_403": "You do not have permission to access this page",
|
||||||
|
"error_404": "Page not found",
|
||||||
|
"error_500": "Service exception, please contact customer support.",
|
||||||
"generating": {
|
"generating": {
|
||||||
"title": "Preview - Click the video to play"
|
"title": "Preview - Click the video to play"
|
||||||
},
|
},
|
||||||
|
"go_to_home": "Go to Homepage",
|
||||||
"history": {
|
"history": {
|
||||||
"delete_confirm": "Are you sure you want to delete this video?",
|
"delete_confirm": "Are you sure you want to delete this video?",
|
||||||
"push_success": "Streaming success",
|
"push_success": "Streaming success",
|
||||||
@ -49,6 +48,26 @@
|
|||||||
"username": "Please enter your phone number",
|
"username": "Please enter your phone number",
|
||||||
"welcome": "Welcome"
|
"welcome": "Welcome"
|
||||||
},
|
},
|
||||||
|
"modal": {
|
||||||
|
"hot_news": {
|
||||||
|
"edit_auto": "Smart",
|
||||||
|
"edit_manual": "Manual",
|
||||||
|
"empty_notice_message": "\"Hot News\" has not been filled in yet. Should it be filled in automatically by the system?",
|
||||||
|
"empty_notice_title": "Notice",
|
||||||
|
"title": "Hot news"
|
||||||
|
},
|
||||||
|
"push_article": {
|
||||||
|
"action_all": "Still generating",
|
||||||
|
"action_cancel": "Cancel",
|
||||||
|
"action_skip": "Skip the news",
|
||||||
|
"content_error": "<span class=\"modal-count-normal\">{{count}}</span> news are selected, and <span class=\"modal-count-warning\">{{error_count}}</span> metahuman contents are too short in these news below. Do you want to transfer them to videos?",
|
||||||
|
"content_error_single": "<span class=\"modal-count-normal\">{{count}}</span> news is selected, and the metahuman content is too short in this news. Do you want to transfer it to a video?",
|
||||||
|
"content_normal": "<span class=\"modal-count-normal\">{{count}}</span> news are selected, Do you want to transfer them into videos?",
|
||||||
|
"content_normal_single": "<span class=\"modal-count-normal\">{{count}}</span> news is selected. Do you want to transfer it to a video?",
|
||||||
|
"error_title": "Abnormal news"
|
||||||
|
},
|
||||||
|
"warning": "Warning"
|
||||||
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
"editing": "Editing",
|
"editing": "Editing",
|
||||||
"generating": "Generating",
|
"generating": "Generating",
|
||||||
@ -89,8 +108,8 @@
|
|||||||
"get_detail_error": "Get new details failed",
|
"get_detail_error": "Get new details failed",
|
||||||
"image_count": "Images",
|
"image_count": "Images",
|
||||||
"materials": {
|
"materials": {
|
||||||
"title": "News Materials",
|
"add_group": "Add Group",
|
||||||
"add_group": "Add Group"
|
"title": "News Materials"
|
||||||
},
|
},
|
||||||
"news_all_source": "All",
|
"news_all_source": "All",
|
||||||
"push_empty": "please select the news to edit",
|
"push_empty": "please select the news to edit",
|
||||||
@ -118,6 +137,7 @@
|
|||||||
"text": "Select",
|
"text": "Select",
|
||||||
"total": "Total: {{count}}"
|
"total": "Total: {{count}}"
|
||||||
},
|
},
|
||||||
|
"service_error": "Service exception, please contact customer support.",
|
||||||
"time_filter": {
|
"time_filter": {
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"last_week": "Last week",
|
"last_week": "Last week",
|
||||||
@ -142,8 +162,8 @@
|
|||||||
"delete_description_count": "Are you sure you want to delete these {{count}} videos?",
|
"delete_description_count": "Are you sure you want to delete these {{count}} videos?",
|
||||||
"delete_empty": "Select the video you want to delete",
|
"delete_empty": "Select the video you want to delete",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"generating": "Generating",
|
|
||||||
"generate_failed": "Generate Failed",
|
"generate_failed": "Generate Failed",
|
||||||
|
"generating": "Generating",
|
||||||
"playing": "Playing",
|
"playing": "Playing",
|
||||||
"push_confirm": "Are you sure you want to streaming these video?",
|
"push_confirm": "Are you sure you want to streaming these video?",
|
||||||
"push_empty": "Select the video you want to streaming",
|
"push_empty": "Select the video you want to streaming",
|
||||||
@ -159,18 +179,5 @@
|
|||||||
"title_generated_time": "Time stamp",
|
"title_generated_time": "Time stamp",
|
||||||
"title_operation": "",
|
"title_operation": "",
|
||||||
"title_thumb": "Cover"
|
"title_thumb": "Cover"
|
||||||
},
|
|
||||||
"modal": {
|
|
||||||
"warning": "Warning",
|
|
||||||
"push_article": {
|
|
||||||
"content_normal": "<span class=\"modal-count-normal\">{{count}}</span> news are selected, Do you want to transfer them into videos?",
|
|
||||||
"content_normal_single": "<span class=\"modal-count-normal\">{{count}}</span> news is selected. Do you want to transfer it to a video?",
|
|
||||||
"content_error": "<span class=\"modal-count-normal\">{{count}}</span> news are selected, and <span class=\"modal-count-warning\">{{error_count}}</span> metahuman contents are too short in these news below. Do you want to transfer them to videos?",
|
|
||||||
"content_error_single": "<span class=\"modal-count-normal\">{{count}}</span> news is selected, and the metahuman content is too short in this news. Do you want to transfer it to a video?",
|
|
||||||
"error_title": "Abnormal news",
|
|
||||||
"action_cancel": "Cancel",
|
|
||||||
"action_skip": "Skip the news",
|
|
||||||
"action_all": "Still generating"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,8 @@
|
|||||||
{
|
{
|
||||||
"AppTitle": "数字人直播",
|
"AppTitle": "数字人直播",
|
||||||
"go_to_home": "返回首页" ,
|
|
||||||
"Hello": "你好",
|
"Hello": "你好",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"close": "关闭",
|
"close": "关闭",
|
||||||
"service_error": "新闻异常,无法生成,请咨询客服",
|
|
||||||
"error_401": "您没有权限访问本页面",
|
|
||||||
"error_403": "您没有权限访问本页面",
|
|
||||||
"error_404": "访问的页面不存在",
|
|
||||||
"error_500": "服务异常,请咨询客服.",
|
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"push_title": "推流提示",
|
"push_title": "推流提示",
|
||||||
"push_video": "是否确定一键推流选中新闻视频?",
|
"push_video": "是否确定一键推流选中新闻视频?",
|
||||||
@ -20,9 +14,14 @@
|
|||||||
"delete_failed": "删除失败",
|
"delete_failed": "删除失败",
|
||||||
"delete_success": "删除成功",
|
"delete_success": "删除成功",
|
||||||
"download": "下载",
|
"download": "下载",
|
||||||
|
"error_401": "您没有权限访问本页面",
|
||||||
|
"error_403": "您没有权限访问本页面",
|
||||||
|
"error_404": "访问的页面不存在",
|
||||||
|
"error_500": "服务异常,请咨询客服.",
|
||||||
"generating": {
|
"generating": {
|
||||||
"title": "预览视频 - 点击视频列表播放"
|
"title": "预览视频 - 点击视频列表播放"
|
||||||
},
|
},
|
||||||
|
"go_to_home": "返回首页",
|
||||||
"history": {
|
"history": {
|
||||||
"delete_confirm": "是否要删除该视频",
|
"delete_confirm": "是否要删除该视频",
|
||||||
"push_success": "一键推流成功,已推流至数字人直播间,请查看!",
|
"push_success": "一键推流成功,已推流至数字人直播间,请查看!",
|
||||||
@ -49,6 +48,26 @@
|
|||||||
"username": "请输入账号",
|
"username": "请输入账号",
|
||||||
"welcome": "欢迎登录"
|
"welcome": "欢迎登录"
|
||||||
},
|
},
|
||||||
|
"modal": {
|
||||||
|
"hot_news": {
|
||||||
|
"edit_auto": "智能填充",
|
||||||
|
"edit_manual": "手动编辑",
|
||||||
|
"empty_notice_message": "“新闻热点”尚未填写,是否由系统自动填充?",
|
||||||
|
"empty_notice_title": "操作提示",
|
||||||
|
"title": "新闻热点"
|
||||||
|
},
|
||||||
|
"push_article": {
|
||||||
|
"action_all": "全部生成",
|
||||||
|
"action_cancel": "全部取消",
|
||||||
|
"action_skip": "跳过异常新闻",
|
||||||
|
"content_error": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,<span class=\"modal-count-warning\">{{error_count}}</span>条新闻数字人播报字数过少,是否生成全部<span class=\"modal-count-normal\">{{count}}</span>条视频?",
|
||||||
|
"content_error_single": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,<span class=\"modal-count-warning\">{{error_count}}</span>条新闻数字人播报字数过少,是否生成全部<span class=\"modal-count-normal\">{{count}}</span>条视频?",
|
||||||
|
"content_normal": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,是否全部生成?",
|
||||||
|
"content_normal_single": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,是否生成?",
|
||||||
|
"error_title": "异常新闻"
|
||||||
|
},
|
||||||
|
"warning": "操作提示"
|
||||||
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
"editing": "新闻编辑",
|
"editing": "新闻编辑",
|
||||||
"generating": "视频生成",
|
"generating": "视频生成",
|
||||||
@ -89,8 +108,8 @@
|
|||||||
"get_detail_error": "获取新闻详情失败",
|
"get_detail_error": "获取新闻详情失败",
|
||||||
"image_count": "图片数",
|
"image_count": "图片数",
|
||||||
"materials": {
|
"materials": {
|
||||||
"title": "新闻素材",
|
"add_group": "新增分组",
|
||||||
"add_group": "新增分组"
|
"title": "新闻素材"
|
||||||
},
|
},
|
||||||
"news_all_source": "全部来源",
|
"news_all_source": "全部来源",
|
||||||
"push_empty": "请选择要推入编辑的新闻",
|
"push_empty": "请选择要推入编辑的新闻",
|
||||||
@ -118,6 +137,7 @@
|
|||||||
"text": "选择",
|
"text": "选择",
|
||||||
"total": "总共 {{count}} 条"
|
"total": "总共 {{count}} 条"
|
||||||
},
|
},
|
||||||
|
"service_error": "新闻异常,无法生成,请咨询客服",
|
||||||
"time_filter": {
|
"time_filter": {
|
||||||
"all": "所有时间",
|
"all": "所有时间",
|
||||||
"last_week": "近一周",
|
"last_week": "近一周",
|
||||||
@ -142,8 +162,8 @@
|
|||||||
"delete_description_count": "已选择{{count}}条,确定要全部删除吗?",
|
"delete_description_count": "已选择{{count}}条,确定要全部删除吗?",
|
||||||
"delete_empty": "请选择要删除的视频",
|
"delete_empty": "请选择要删除的视频",
|
||||||
"download": "下载视频",
|
"download": "下载视频",
|
||||||
"generating": "生成中",
|
|
||||||
"generate_failed": "生成失败",
|
"generate_failed": "生成失败",
|
||||||
|
"generating": "生成中",
|
||||||
"playing": "播放中",
|
"playing": "播放中",
|
||||||
"push_confirm": "是否确定一键推流选中新闻视频?",
|
"push_confirm": "是否确定一键推流选中新闻视频?",
|
||||||
"push_empty": "请选择要推流的新闻视频",
|
"push_empty": "请选择要推流的新闻视频",
|
||||||
@ -159,18 +179,5 @@
|
|||||||
"title_generated_time": "生成时间",
|
"title_generated_time": "生成时间",
|
||||||
"title_operation": "操作",
|
"title_operation": "操作",
|
||||||
"title_thumb": "缩略图"
|
"title_thumb": "缩略图"
|
||||||
},
|
|
||||||
"modal": {
|
|
||||||
"warning": "操作提示",
|
|
||||||
"push_article": {
|
|
||||||
"content_normal": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,是否全部生成?",
|
|
||||||
"content_normal_single": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,是否生成?",
|
|
||||||
"content_error": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,<span class=\"modal-count-warning\">{{error_count}}</span>条新闻数字人播报字数过少,是否生成全部<span class=\"modal-count-normal\">{{count}}</span>条视频?",
|
|
||||||
"content_error_single": "已选中<span class=\"modal-count-normal\">{{count}}</span>条新闻,<span class=\"modal-count-warning\">{{error_count}}</span>条新闻数字人播报字数过少,是否生成全部<span class=\"modal-count-normal\">{{count}}</span>条视频?",
|
|
||||||
"error_title": "异常新闻",
|
|
||||||
"action_cancel": "全部取消",
|
|
||||||
"action_skip": "跳过异常新闻",
|
|
||||||
"action_all": "全部生成"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,13 +20,8 @@ export function getById(id: Id) {
|
|||||||
return post<ArticleDetail>({url: '/article/detail/' + id})
|
return post<ArticleDetail>({url: '/article/detail/' + id})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function save(title: string, metahuman_text: string, content_group: BlockContent[][], id?: number) {
|
export function save(params:{title: string, metahuman_text: string, content_group: BlockContent[][],hot_news: string[], id?: number}) {
|
||||||
return post<{ content: string }>(id && id > 0 ? '/article/modify' : '/article/create/new', {
|
return post<{ content: string }>(params.id && params.id > 0 ? '/article/modify' : '/article/create/new',params)
|
||||||
title,
|
|
||||||
metahuman_text,
|
|
||||||
content_group,
|
|
||||||
id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function push2video(article_ids: Id[]) {
|
export function push2video(article_ids: Id[]) {
|
||||||
|
@ -17,21 +17,24 @@ export function deleteHistories(ids: Id[]) {
|
|||||||
* @param content_group
|
* @param content_group
|
||||||
* @param article_id
|
* @param article_id
|
||||||
*/
|
*/
|
||||||
export function regenerate(title: string, metahuman_text: string, content_group: BlockContent[][], article_id?: Id) {
|
export function regenerate(params:{title: string, metahuman_text: string, content_group: BlockContent[][], id?: Id}) {
|
||||||
return post<{ content: string }>({
|
return post<{ content: string }>({
|
||||||
url: '/video/regenerate',
|
url: '/video/regenerate',
|
||||||
data: {
|
data: {
|
||||||
title,
|
...params,
|
||||||
metahuman_text,
|
article_id:params.id
|
||||||
content_group,
|
|
||||||
article_id
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 重新生成视频
|
// 重新生成视频
|
||||||
export async function regenerateById(article_id: Id) {
|
export async function regenerateById(article_id: Id) {
|
||||||
const article = await getArticle(article_id);
|
const article = await getArticle(article_id);
|
||||||
return await regenerate(article.title, article.metahuman_text, article.content_group, article_id)
|
return await regenerate({
|
||||||
|
title:article.title,
|
||||||
|
metahuman_text:article.metahuman_text,
|
||||||
|
content_group:article.content_group,
|
||||||
|
id:article_id
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getById(id: Id) {
|
export function getById(id: Id) {
|
||||||
|
2
src/types/core.d.ts
vendored
2
src/types/core.d.ts
vendored
@ -32,6 +32,8 @@ declare interface ArticleDetail {
|
|||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
metahuman_text: string;
|
metahuman_text: string;
|
||||||
|
hot_news_mode?: string;
|
||||||
|
hot_news: string[]; // 4月 6 日新增
|
||||||
content_group: BlockContent[][]
|
content_group: BlockContent[][]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user