fixed: ts build error
This commit is contained in:
parent
4d5449364a
commit
1acdc2a99d
@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {Popconfirm, Space} from "antd";
|
import {Popconfirm} from "antd";
|
||||||
|
|
||||||
import {IconAdd, IconDelete} from "@/components/icons";
|
import {IconAdd, IconDelete} from "@/components/icons";
|
||||||
import ImageList from "@/components/article/list.tsx";
|
import ImageList from "@/components/article/list.tsx";
|
||||||
@ -10,7 +10,7 @@ import styles from './article.module.scss'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
index?: number;
|
index: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
blocks: BlockContent[];
|
blocks: BlockContent[];
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
@ -51,22 +51,6 @@ export default function ArticleBlock(
|
|||||||
errorMessage
|
errorMessage
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const blocks = rebuildBlockArray(defaultBlocks)
|
const blocks = rebuildBlockArray(defaultBlocks)
|
||||||
const handleBlockRemove = (index: number) => {
|
|
||||||
// 删除当前项
|
|
||||||
onChange?.(blocks.filter((_, idx) => index !== idx))
|
|
||||||
}
|
|
||||||
const firstTextBlockIndex = blocks.findIndex(it => it.type === 'text')
|
|
||||||
// 新增
|
|
||||||
const handleAddBlock = (type: 'text' | 'image', insertIndex: number = -1) => {
|
|
||||||
const newBlock: BlockContent = type === 'text' ? {type: 'text', content: ''} : {type: 'image', content: ''};
|
|
||||||
const _blocks = [...blocks]
|
|
||||||
if (insertIndex == -1 || insertIndex >= blocks.length) { // -1或者越界表示新增
|
|
||||||
_blocks.push(newBlock)
|
|
||||||
} else {
|
|
||||||
_blocks.splice(insertIndex, 0, newBlock)
|
|
||||||
}
|
|
||||||
onChange?.(_blocks)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleBlockChange = (index: number, block: BlockContent) => {
|
const handleBlockChange = (index: number, block: BlockContent) => {
|
||||||
const _blocks = [...blocks]
|
const _blocks = [...blocks]
|
||||||
|
@ -39,7 +39,7 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
}
|
}
|
||||||
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, props.id > 0 ? props.id : undefined).then(() => {
|
save(title, groups, props.id && props.id > 0 ? props.id : undefined).then(() => {
|
||||||
props.onClose?.(true)
|
props.onClose?.(true)
|
||||||
}).catch(e=>{
|
}).catch(e=>{
|
||||||
setState({error: e.data || '保存失败,请重试!'})
|
setState({error: e.data || '保存失败,请重试!'})
|
||||||
@ -65,7 +65,7 @@ export default function ArticleEditModal(props: Props) {
|
|||||||
|
|
||||||
return (<Modal
|
return (<Modal
|
||||||
title={'编辑文章'}
|
title={'编辑文章'}
|
||||||
open={props.id >= 0}
|
open={!!props.id && props.id >= 0}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
keyboard={false}
|
keyboard={false}
|
||||||
width={800}
|
width={800}
|
||||||
|
@ -14,7 +14,7 @@ type Props = {
|
|||||||
|
|
||||||
function pushBlocksToGroup(blocks: BlockContent[],groups: BlockContent[][]){
|
function pushBlocksToGroup(blocks: BlockContent[],groups: BlockContent[][]){
|
||||||
const lastGroup = groups[groups.length - 1]
|
const lastGroup = groups[groups.length - 1]
|
||||||
if (lastGroup && lastGroup.filter(s=>s.type == 'text') == 0) {
|
if (lastGroup && lastGroup.filter(s=>s.type == 'text').length == 0) {
|
||||||
// 如果上一个group中没有文本则直接合并
|
// 如果上一个group中没有文本则直接合并
|
||||||
lastGroup.push(...blocks)
|
lastGroup.push(...blocks)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, {useState} from "react";
|
import React, {useState} from "react";
|
||||||
import {Input, Popconfirm, Spin, Upload, UploadProps} from "antd";
|
import {Input, Popconfirm, Spin, Upload, UploadProps} from "antd";
|
||||||
import {CloseOutlined,CloudUploadOutlined} from "@ant-design/icons";
|
import {CloseOutlined} from "@ant-design/icons";
|
||||||
import {clsx} from "clsx";
|
import {clsx} from "clsx";
|
||||||
|
|
||||||
import styles from './article.module.scss'
|
import styles from './article.module.scss'
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
import {BlockImage} from "@/components/article/item.tsx";
|
import {BlockImage} from "@/components/article/item.tsx";
|
||||||
|
|
||||||
import styles from './article.module.scss'
|
import styles from './article.module.scss'
|
||||||
|
@ -2,13 +2,14 @@ import React, {useState} from "react";
|
|||||||
import {Button, Modal} from "antd";
|
import {Button, Modal} from "antd";
|
||||||
import {ButtonType} from "antd/es/button";
|
import {ButtonType} from "antd/es/button";
|
||||||
import {showErrorToast, showToast} from "@/components/message.ts";
|
import {showErrorToast, showToast} from "@/components/message.ts";
|
||||||
|
import {BizError} from "@/service/types.ts";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
selected: any[],
|
selected: any[],
|
||||||
type?: ButtonType;
|
type?: ButtonType;
|
||||||
emptyMessage: string,
|
emptyMessage: string,
|
||||||
confirmMessage: React.ReactNode,
|
confirmMessage: React.ReactNode,
|
||||||
onProcess: (ids: Id[]) => Promise<void>
|
onProcess: (ids: Id[]) => Promise<any|void>
|
||||||
successMessage?: string;
|
successMessage?: string;
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
@ -32,7 +33,7 @@ export default function ButtonBatch(
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showErrorToast(e)
|
showErrorToast(e as unknown as BizError)
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import {useSortable} from "@dnd-kit/sortable";
|
|||||||
import {useSetState} from "ahooks";
|
import {useSetState} from "ahooks";
|
||||||
import React, {useEffect} from "react";
|
import React, {useEffect} from "react";
|
||||||
import {clsx} from "clsx";
|
import {clsx} from "clsx";
|
||||||
import {Image, Popconfirm} from "antd";
|
import {Popconfirm} from "antd";
|
||||||
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled} from "@ant-design/icons";
|
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled} from "@ant-design/icons";
|
||||||
|
|
||||||
import ImageCover from '@/assets/images/cover.png'
|
import ImageCover from '@/assets/images/cover.png'
|
||||||
@ -51,7 +51,7 @@ export const VideoListItem = (
|
|||||||
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 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} alt={video.video_title}/>
|
<img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover} />
|
||||||
</div>
|
</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">
|
||||||
|
@ -2,19 +2,10 @@ import React, {createContext, useEffect, useReducer} from "react";
|
|||||||
|
|
||||||
import Loader from "@/components/loader";
|
import Loader from "@/components/loader";
|
||||||
import {getAuthToken, setAuthToken} from "@/hooks/useAuth.ts";
|
import {getAuthToken, setAuthToken} from "@/hooks/useAuth.ts";
|
||||||
import {auth, getUserInfo} from "@/service/api/user.ts";
|
import {auth} from "@/service/api/user.ts";
|
||||||
|
|
||||||
|
|
||||||
const UserRoleStorageKey = 'user-current-role';
|
const UserRoleStorageKey = 'user-current-role';
|
||||||
|
|
||||||
function getCurrentRole() {
|
|
||||||
return (localStorage.getItem(UserRoleStorageKey)) as UserRole
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setCurrentRole(role: UserRole) {
|
|
||||||
localStorage.setItem(UserRoleStorageKey, role)
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeRoleStorage() {
|
function removeRoleStorage() {
|
||||||
localStorage.removeItem(UserRoleStorageKey)
|
localStorage.removeItem(UserRoleStorageKey)
|
||||||
}
|
}
|
||||||
@ -87,7 +78,7 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
|
|||||||
}
|
}
|
||||||
// 登出
|
// 登出
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
setAuthToken(null)
|
setAuthToken(null,null,-1)
|
||||||
removeRoleStorage()
|
removeRoleStorage()
|
||||||
dispatch({
|
dispatch({
|
||||||
action: 'logout',
|
action: 'logout',
|
||||||
|
@ -18,7 +18,7 @@ const clearAuth = () => {
|
|||||||
localStorage.removeItem(AppConfig.AUTH_TOKEN_KEY);
|
localStorage.removeItem(AppConfig.AUTH_TOKEN_KEY);
|
||||||
localStorage.removeItem(AppConfig.AUTHED_PERSON_DATA_KEY);
|
localStorage.removeItem(AppConfig.AUTHED_PERSON_DATA_KEY);
|
||||||
}
|
}
|
||||||
export const setAuthToken = (token: string | null,profileData:UserProfile, expiry_time = -1) => {
|
export const setAuthToken = (token: string | null,profileData:UserProfile|null, expiry_time = -1) => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
clearAuth();
|
clearAuth();
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import React from 'react'
|
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
|
|
||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
|
@ -2,7 +2,6 @@ import {Button, Modal} from "antd";
|
|||||||
|
|
||||||
import {Player} from "@/components/video/player.tsx";
|
import {Player} from "@/components/video/player.tsx";
|
||||||
|
|
||||||
import { ArticleGroupList } from "@/_local/mock-data";
|
|
||||||
import ArticleGroup from "@/components/article/group";
|
import ArticleGroup from "@/components/article/group";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -31,7 +30,7 @@ export default function VideoDetail({video, onClose}: Props) {
|
|||||||
<span>标题: xxxxxxxx</span>
|
<span>标题: xxxxxxxx</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="content-container max-h-[500px] overflow-auto pr-1 mt-4">
|
<div className="content-container max-h-[500px] overflow-auto pr-1 mt-4">
|
||||||
<ArticleGroup groups={ArticleGroupList}/>
|
<ArticleGroup groups={[]}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
import React, {useState} from 'react';
|
|
||||||
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
||||||
import {
|
|
||||||
DndContext,
|
|
||||||
closestCenter,
|
|
||||||
KeyboardSensor,
|
|
||||||
PointerSensor,
|
|
||||||
useSensor,
|
|
||||||
useSensors,
|
|
||||||
} from '@dnd-kit/core';
|
|
||||||
|
|
||||||
import {
|
|
||||||
useSortable, arrayMove,
|
|
||||||
SortableContext,
|
|
||||||
sortableKeyboardCoordinates,
|
|
||||||
verticalListSortingStrategy,
|
|
||||||
} from '@dnd-kit/sortable';
|
|
||||||
|
|
||||||
type TestData = {
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
type SortableItemProps = {
|
|
||||||
data: TestData;
|
|
||||||
active?: boolean;
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function SortableItem(props: SortableItemProps) {
|
|
||||||
const {
|
|
||||||
attributes,
|
|
||||||
listeners,
|
|
||||||
setNodeRef,
|
|
||||||
transform,
|
|
||||||
transition,
|
|
||||||
} = useSortable({
|
|
||||||
resizeObserverConfig: {},
|
|
||||||
id: props.data.id
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={setNodeRef} style={{
|
|
||||||
transform: `translateY(${transform ? transform?.y:0}px)`,
|
|
||||||
transition,
|
|
||||||
// marginTop:10,
|
|
||||||
// marginBottom:10
|
|
||||||
}} className={props.active ? 'drop-shadow shadow-blue-400 drop-shadow-md' : ''}>
|
|
||||||
<div className="h-[100px] mb-5 border p-5 rounded bg-white flex justify-between items-center">
|
|
||||||
<div className="flex-1">
|
|
||||||
<div>
|
|
||||||
{JSON.stringify(props.data)}
|
|
||||||
</div>
|
|
||||||
<div>{JSON.stringify(transform)}</div>
|
|
||||||
</div>
|
|
||||||
<button {...attributes} {...listeners} className="cursor-move">Move</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SortDemo() {
|
|
||||||
const [items, setItems] = useState<TestData[]>([
|
|
||||||
{id: 1},
|
|
||||||
{id: 2},
|
|
||||||
{id: 3},
|
|
||||||
{id: 4},
|
|
||||||
{id: 5},
|
|
||||||
]);
|
|
||||||
const [activeId, setActiveId] = useState<number>();
|
|
||||||
|
|
||||||
function handleDragEnd(event) {
|
|
||||||
const {active, over} = event;
|
|
||||||
setActiveId(undefined)
|
|
||||||
console.log(JSON.stringify({
|
|
||||||
items,
|
|
||||||
active: active.id,
|
|
||||||
over: over.id,
|
|
||||||
}))
|
|
||||||
if (active.id !== over.id) {
|
|
||||||
setItems((items) => {
|
|
||||||
const oldIndex = items.findIndex(s=>s.id == active.id);
|
|
||||||
const newIndex = items.findIndex(s=>s.id == over.id);
|
|
||||||
const _newArr = arrayMove(items, oldIndex, newIndex);
|
|
||||||
console.log(JSON.stringify({
|
|
||||||
_newArr,
|
|
||||||
items,
|
|
||||||
oldIndex,
|
|
||||||
newIndex
|
|
||||||
}))
|
|
||||||
return _newArr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// const sensors = useSensors(
|
|
||||||
// useSensor(PointerSensor),
|
|
||||||
// useSensor(KeyboardSensor, {
|
|
||||||
// coordinateGetter: sortableKeyboardCoordinates,
|
|
||||||
// })
|
|
||||||
// );
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div>{JSON.stringify(items)}</div>
|
|
||||||
<DndContext
|
|
||||||
modifiers={[restrictToVerticalAxis]}
|
|
||||||
onDragEnd={handleDragEnd}
|
|
||||||
onDragStart={e => {
|
|
||||||
if (e.active && e.active.id) {
|
|
||||||
setActiveId(Number(e.active.id))
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SortableContext
|
|
||||||
items={items}
|
|
||||||
>
|
|
||||||
{items.map(it => <SortableItem active={it.id == activeId} key={it.id} data={it} id={it.id}/>)}
|
|
||||||
</SortableContext>
|
|
||||||
</DndContext>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
@ -139,7 +139,7 @@ export default function LiveIndex() {
|
|||||||
return clearAllTimer;
|
return clearAllTimer;
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const processDeleteVideo = async (ids: number[]) => {
|
const processDeleteVideo = async (ids: Id[]) => {
|
||||||
deleteByIds(ids).then(() => {
|
deleteByIds(ids).then(() => {
|
||||||
showToast('删除成功!', 'success')
|
showToast('删除成功!', 'success')
|
||||||
loadList()
|
loadList()
|
||||||
|
@ -4,63 +4,63 @@ import React, {useEffect, useMemo} from "react";
|
|||||||
|
|
||||||
const prevSelectValues: Id[][] = [];
|
const prevSelectValues: Id[][] = [];
|
||||||
|
|
||||||
function buildValues(options: OptionItem[], selectedValues: Id[][], allValue = -1) {
|
// function buildValues(options: OptionItem[], selectedValues: Id[][], allValue = -1) {
|
||||||
const values: Id[][] = []
|
// const values: Id[][] = []
|
||||||
selectedValues.forEach(item => {
|
// selectedValues.forEach(item => {
|
||||||
if (item.length === 0) {
|
// if (item.length === 0) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (item.length == 1) {
|
// if (item.length == 1) {
|
||||||
if (item[0] == allValue) {
|
// if (item[0] == allValue) {
|
||||||
values.push([allValue]);
|
// values.push([allValue]);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// 只有1个值 表示选择了一级分类下的所有二级分类
|
// // 只有1个值 表示选择了一级分类下的所有二级分类
|
||||||
const op = options.find(option => option.value === item[0]);
|
// const op = options.find(option => option.value === item[0]);
|
||||||
if (!op || !op.children || op.children.length === 0) {
|
// if (!op || !op.children || op.children.length === 0) {
|
||||||
// 没有找到或者没有二级分类
|
// // 没有找到或者没有二级分类
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// 只有一级分类
|
// // 只有一级分类
|
||||||
op.children.forEach(child => {
|
// op.children.forEach(child => {
|
||||||
values.push([item[0], child.value]);
|
// values.push([item[0], child.value]);
|
||||||
})
|
// })
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
values.push(item)
|
// values.push(item)
|
||||||
})
|
// })
|
||||||
return values
|
// return values
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 获取两个数组的差集
|
// 获取两个数组的差集
|
||||||
function getValuesDiff(values: Id[][], prevValues: Id[][]) {
|
// function getValuesDiff(values: Id[][], prevValues: Id[][]) {
|
||||||
if (values.length != prevValues.length) {
|
// if (values.length != prevValues.length) {
|
||||||
const moreItems = values.length > prevValues.length ? values : prevValues;
|
// const moreItems = values.length > prevValues.length ? values : prevValues;
|
||||||
const lessItems = values.length > prevValues.length ? prevValues : values;
|
// const lessItems = values.length > prevValues.length ? prevValues : values;
|
||||||
const lessItemsKeys = lessItems.map(s => s.join('-'));
|
// const lessItemsKeys = lessItems.map(s => s.join('-'));
|
||||||
for (let i = 0; i < moreItems.length; i++) {
|
// for (let i = 0; i < moreItems.length; i++) {
|
||||||
const item = moreItems[i], index = lessItemsKeys.indexOf(item.join('-'));
|
// const item = moreItems[i], index = lessItemsKeys.indexOf(item.join('-'));
|
||||||
if (index === -1) {
|
// if (index === -1) {
|
||||||
return item;
|
// return item;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
function getAllValue(options: OptionItem[]) {
|
// function getAllValue(options: OptionItem[]) {
|
||||||
const values: Id[][] = []
|
// const values: Id[][] = []
|
||||||
options.forEach(option => {
|
// options.forEach(option => {
|
||||||
if (option.children && option.children.length > 0) {
|
// if (option.children && option.children.length > 0) {
|
||||||
option.children.forEach(child => {
|
// option.children.forEach(child => {
|
||||||
values.push([option.value, child.value]);
|
// values.push([option.value, child.value]);
|
||||||
})
|
// })
|
||||||
} else {
|
// } else {
|
||||||
values.push([option.value]);
|
// values.push([option.value]);
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
return values
|
// return values
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default function ArticleCascader(props: {
|
export default function ArticleCascader(props: {
|
||||||
options: OptionItem[];
|
options: OptionItem[];
|
||||||
@ -71,9 +71,9 @@ export default function ArticleCascader(props: {
|
|||||||
// 清除上一次的选中值
|
// 清除上一次的选中值
|
||||||
prevSelectValues.length = 0;
|
prevSelectValues.length = 0;
|
||||||
}, [])
|
}, [])
|
||||||
const allOptionValue = useMemo(() => {
|
// const allOptionValue = useMemo(() => {
|
||||||
return getAllValue(props.options)
|
// return getAllValue(props.options)
|
||||||
}, [props.options])
|
// }, [props.options])
|
||||||
|
|
||||||
const setSelectValues = (value: Id[][]) => {
|
const setSelectValues = (value: Id[][]) => {
|
||||||
_setSelectValues(value)
|
_setSelectValues(value)
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import {Button, Pagination, Table, TableColumnsType, TableProps, Typography} from "antd";
|
import {Button, Pagination, Table, TableColumnsType, TableProps, Typography} from "antd";
|
||||||
|
|
||||||
import {Card} from "@/components/card";
|
import {Card} from "@/components/card";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useState} from "react";
|
||||||
import {useRequest} from "ahooks";
|
import {useRequest} from "ahooks";
|
||||||
import {formatTime} from "@/util/strings.ts";
|
import {formatTime} from "@/util/strings.ts";
|
||||||
import ArticleEditModal from "@/components/article/edit-modal.tsx";
|
import ArticleEditModal from "@/components/article/edit-modal.tsx";
|
||||||
import {getList} from "@/service/api/article.ts";
|
import {getList} from "@/service/api/article.ts";
|
||||||
import EditSearchForm from "@/pages/news/components/edit-search-form.tsx";
|
import EditSearchForm from "@/pages/news/components/edit-search-form.tsx";
|
||||||
import ButtonPush2Video from "@/pages/news/components/button-push2video.tsx";
|
import ButtonPush2Video from "@/pages/news/components/button-push2video.tsx";
|
||||||
|
import {Key} from "antd/es/table/interface";
|
||||||
|
|
||||||
|
|
||||||
export default function NewEdit() {
|
export default function NewEdit() {
|
||||||
@ -55,8 +56,8 @@ export default function NewEdit() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const rowSelection: TableProps<ListArticleItem>['rowSelection'] = {
|
const rowSelection: TableProps<ListArticleItem>['rowSelection'] = {
|
||||||
onChange: (selectedRowKeys: Id[]) => {
|
onChange: (selectedRowKeys: Key[]) => {
|
||||||
setSelectedRowKeys(selectedRowKeys)
|
setSelectedRowKeys(selectedRowKeys as Id[])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ export default function NewEdit() {
|
|||||||
bordered
|
bordered
|
||||||
pagination={false}
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
{data?.pagination.total > 0 && <div className="footer flex justify-between items-center mt-5">
|
{data?.pagination && data?.pagination.total > 0 && <div className="footer flex justify-between items-center mt-5">
|
||||||
<Pagination
|
<Pagination
|
||||||
current={params.pagination.page}
|
current={params.pagination.page}
|
||||||
total={data?.pagination.total}
|
total={data?.pagination.total}
|
||||||
|
@ -20,7 +20,7 @@ export default function NewsIndex() {
|
|||||||
limit: 10
|
limit: 10
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const [checkedId, setCheckedId] = useState<number[]>([])
|
const [checkedId, setCheckedId] = useState<Id[]>([])
|
||||||
const [activeNews, setActiveNews] = useState<NewsInfo>()
|
const [activeNews, setActiveNews] = useState<NewsInfo>()
|
||||||
|
|
||||||
const [state, setState] = useState<{
|
const [state, setState] = useState<{
|
||||||
@ -66,7 +66,7 @@ export default function NewsIndex() {
|
|||||||
<Checkbox checked={state.checkAll} onChange={e => {
|
<Checkbox checked={state.checkAll} onChange={e => {
|
||||||
setState({checkAll: e.target.checked})
|
setState({checkAll: e.target.checked})
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
setCheckedId(data.list.map(item => item.id))
|
setCheckedId(data?.list?.map(item => item.id) || [])
|
||||||
} else {
|
} else {
|
||||||
setCheckedId([])
|
setCheckedId([])
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ export default function NewsIndex() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{data?.pagination.total > 0 ? <div className="flex justify-center mt-10">
|
{data?.pagination && data?.pagination.total > 0 ? <div className="flex justify-center mt-10">
|
||||||
<Pagination
|
<Pagination
|
||||||
current={params.pagination.page}
|
current={params.pagination.page}
|
||||||
total={data?.pagination.total}
|
total={data?.pagination.total}
|
||||||
|
@ -85,7 +85,7 @@ export default function FormLogin() {
|
|||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button disabled={disabled || loading} loading={loading} type="primary" size={'large'} htmlType="submit"
|
<Button disabled={disabled || loading} loading={loading} type="primary" size={'large'} htmlType="submit"
|
||||||
block shape={'round'}>
|
block shape={'round'}>
|
||||||
{login ? '登录中' : '立即登录'}
|
{loading ? '登录中...' : '立即登录'}
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -2,7 +2,6 @@ import axios from 'axios';
|
|||||||
import {stringify} from 'qs'
|
import {stringify} from 'qs'
|
||||||
import {BizError} from './types';
|
import {BizError} from './types';
|
||||||
import {getAuthToken} from "@/hooks/useAuth.ts";
|
import {getAuthToken} from "@/hooks/useAuth.ts";
|
||||||
import {showToast} from "@/components/message.ts";
|
|
||||||
|
|
||||||
const JSON_FORMAT: string = 'application/json';
|
const JSON_FORMAT: string = 'application/json';
|
||||||
const REQUEST_TIMEOUT = 300000; // 超时时长5min
|
const REQUEST_TIMEOUT = 300000; // 超时时长5min
|
||||||
|
4
src/types/api.d.ts
vendored
4
src/types/api.d.ts
vendored
@ -82,6 +82,7 @@ declare interface ListCrawlerNewsItem extends BasicArticleInfo {
|
|||||||
}
|
}
|
||||||
declare interface VideoInfo {
|
declare interface VideoInfo {
|
||||||
id: number;
|
id: number;
|
||||||
|
video_title: string;
|
||||||
title: string;
|
title: string;
|
||||||
cover: string;
|
cover: string;
|
||||||
oss_video_url: string;
|
oss_video_url: string;
|
||||||
@ -92,6 +93,7 @@ declare interface VideoInfo {
|
|||||||
// room live
|
// room live
|
||||||
declare interface LiveVideoInfo {
|
declare interface LiveVideoInfo {
|
||||||
id: number;
|
id: number;
|
||||||
|
title: string;
|
||||||
video_id: number;
|
video_id: number;
|
||||||
video_title: string;
|
video_title: string;
|
||||||
cover: string;
|
cover: string;
|
||||||
@ -103,5 +105,5 @@ declare interface LiveVideoInfo {
|
|||||||
|
|
||||||
declare interface LiveState{
|
declare interface LiveState{
|
||||||
id: number;
|
id: number;
|
||||||
live_start_time?: number;
|
live_start_time: number;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@
|
|||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
"allowSyntheticDefaultImports": true
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user