fixed: 新闻素材来源修改多选为单选;修改视频时长统计(视频时长单位为毫秒);
update: 更新导航栏文字(AI视频->视频生成)
This commit is contained in:
parent
1acdc2a99d
commit
e1a4005e27
25
README.md
Normal file
25
README.md
Normal file
@ -0,0 +1,25 @@
|
||||
## 数值人直播间
|
||||
### Start
|
||||
|
||||
```shell
|
||||
git clone git@e.coding.net:starbite/aixiaodui/fengmang-backend.git
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
打开 [http://localhost:10021/](http://localhost:10021/) 查看效果
|
||||
### Deploy
|
||||
**直接部署**
|
||||
> 需要配置 /mgmt 及 /api 反向代理
|
||||
```shell
|
||||
; 如果需要指定前缀(CDN)或者需要运行在相对路径中,不需要则跳过此命令
|
||||
export PUBLIC_PATH=xxxxxxxx(相应路径)
|
||||
npm run build
|
||||
```
|
||||
生成的资源在dist目录中,将此目录中所有文件放置在待部署web目录即可。
|
||||
|
||||
**使用docker**
|
||||
|
||||
[x] TODO
|
||||
```shell
|
||||
dockercompose up -d
|
||||
```
|
@ -177,7 +177,7 @@ export default function LiveIndex() {
|
||||
const totalDuration = useMemo(() => {
|
||||
if (!videoData || videoData.length == 0) return 0;
|
||||
// 计算总时长
|
||||
return videoData.reduce((sum, v) => sum + v.video_duration, 0);
|
||||
return videoData.reduce((sum, v) => sum + Math.ceil(v.video_duration / 1000), 0);
|
||||
}, [videoData])
|
||||
|
||||
return (<div className="container py-10 page-live">
|
||||
|
@ -11,6 +11,11 @@ type SearchPanelProps = {
|
||||
const pagination = {
|
||||
limit: 10, page: 1
|
||||
}
|
||||
const DEFAULT_STATE = {
|
||||
tag_level_1_id: -1,
|
||||
tag_level_2_id: -1,
|
||||
subOptions: []
|
||||
}
|
||||
export default function SearchPanel({onSearch}: SearchPanelProps) {
|
||||
const tags = useArticleTags();
|
||||
const [params, setParams] = useSetState<ApiArticleSearchParams>({
|
||||
@ -18,36 +23,26 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
|
||||
});
|
||||
|
||||
const [state, setState] = useSetState<{
|
||||
source: string | number;
|
||||
tag_level_1_id: number;
|
||||
tag_level_2_id: number;
|
||||
subOptions: (string | number)[]
|
||||
}>({
|
||||
source: -1,
|
||||
subOptions: []
|
||||
})
|
||||
}>({...DEFAULT_STATE})
|
||||
|
||||
// 二级分类
|
||||
const [subOptions, setSubOptions] = useState<OptionItem[]>([])
|
||||
const onFinish = () => {
|
||||
if(state.source != -1){
|
||||
params.tags = [];
|
||||
state.subOptions.forEach(level2 => {
|
||||
params.tags!.push({
|
||||
level1: state.source,
|
||||
level2
|
||||
})
|
||||
})
|
||||
}else{
|
||||
params.tags = undefined;
|
||||
}
|
||||
|
||||
onSearch?.({
|
||||
...params
|
||||
...params,
|
||||
tag_level_1_id: state.tag_level_1_id > 0?state.tag_level_1_id:undefined,
|
||||
tag_level_2_id: state.tag_level_2_id > 0?state.tag_level_2_id:undefined,
|
||||
pagination
|
||||
})
|
||||
}
|
||||
// 重置
|
||||
const onReset = () => {
|
||||
setParams({pagination, title: ''})
|
||||
setState({source: -1,subOptions: []})
|
||||
setState({...DEFAULT_STATE})
|
||||
setSubOptions([])
|
||||
onSearch?.({pagination})
|
||||
}
|
||||
@ -84,37 +79,31 @@ export default function SearchPanel({onSearch}: SearchPanelProps) {
|
||||
<div className="list-container flex-1">
|
||||
<div className="news-source-lv-1 flex flex-wrap">
|
||||
<div
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.source == -1 ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == -1 ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
onClick={() => {
|
||||
setState({source: -1, subOptions: []})
|
||||
setState({...DEFAULT_STATE})
|
||||
setSubOptions([])
|
||||
}}>全部</div>
|
||||
{
|
||||
tags.filter(s=>s.value !== 999999).map(it => (
|
||||
<div
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.source == it.value ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_1_id == it.value ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
key={it.value}
|
||||
onClick={() => {
|
||||
setState({source: it.value, subOptions: []})
|
||||
setState({tag_level_1_id: Number(it.value),tag_level_2_id:-1})
|
||||
setSubOptions(it.children || [])
|
||||
}}>{it.label}</div>)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{state.source != -1 && subOptions.length > 0 && <div className="news-source-lv-2 bg-gray-100 p-2 rounded mt-2 flex flex-wrap">
|
||||
{state.tag_level_1_id != -1 && subOptions.length > 0 && <div className="news-source-lv-2 bg-gray-100 p-2 rounded mt-2 flex flex-wrap">
|
||||
{
|
||||
subOptions.map(it => (
|
||||
<div
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.subOptions.includes(it.value) ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.tag_level_2_id == it.value ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
key={it.value}
|
||||
onClick={() => {
|
||||
const options = [...state.subOptions]
|
||||
if (options.includes(it.value)) {
|
||||
options.splice(options.indexOf(it.value), 1)
|
||||
} else {
|
||||
options.push(it.value)
|
||||
}
|
||||
setState({subOptions: options})
|
||||
setState({tag_level_2_id: Number(it.value)})
|
||||
}}>{it.label}</div>)
|
||||
)
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ export default function VideoIndex() {
|
||||
const totalDuration = useMemo(() => {
|
||||
if (!videoData || videoData.length == 0) return 0;
|
||||
// 计算总时长
|
||||
return videoData.reduce((sum, v) => sum + v.duration, 0);
|
||||
return videoData.reduce((sum, v) => sum + Math.ceil(v.duration / 1000), 0);
|
||||
}, [videoData])
|
||||
|
||||
return (<div className="container py-10 page-live">
|
||||
|
@ -17,7 +17,7 @@ const NavItems = [
|
||||
},
|
||||
{
|
||||
key: 'create',
|
||||
name: 'AI视频',
|
||||
name: '视频生成',
|
||||
icon: 'ai',
|
||||
path:'/create'
|
||||
},
|
||||
|
8
src/types/api.d.ts
vendored
8
src/types/api.d.ts
vendored
@ -6,10 +6,10 @@ declare interface ApiRequestPageParams {
|
||||
}
|
||||
|
||||
declare interface ApiArticleSearchParams extends ApiRequestPageParams{
|
||||
// // 1级标签id
|
||||
// tag_level_1_id?: number;
|
||||
// // 2级标签id 没有则为0
|
||||
// tag_level_2_id?: number;
|
||||
// 1级标签id
|
||||
tag_level_1_id?: number;
|
||||
// 2级标签id 没有则为0
|
||||
tag_level_2_id?: number;
|
||||
tags?: {
|
||||
level1: Id;
|
||||
level2: Id;
|
||||
|
@ -32,12 +32,12 @@ export default defineConfig(({mode}) => {
|
||||
port: 10021,
|
||||
proxy: {
|
||||
'/mgmt': {
|
||||
target: 'http://192.168.0.231:9999',
|
||||
target: 'http://124.220.14.192', // http://124.220.14.192/ 192.168.0.231:9999
|
||||
changeOrigin: true,
|
||||
// rewrite: (path) => path.replace(/^\/api/, '')
|
||||
},
|
||||
'/api': {
|
||||
target: 'http://192.168.0.231:9999',
|
||||
target: 'http://124.220.14.192',
|
||||
changeOrigin: true,
|
||||
// rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user