feat: add live clip batch upload and date platform filters
Allow multi-file live clip uploads with shared date/host/platform and per-clip titles, filter materials by live platform and date range, and fix the migration to alter the mapped materials table.
This commit is contained in:
parent
be43f1a6a5
commit
bea82d67b0
@ -107,7 +107,10 @@ export default function MaterialLibraryPage() {
|
|||||||
const [selectedScene, setSelectedScene] = useState('')
|
const [selectedScene, setSelectedScene] = useState('')
|
||||||
const [selectedMaterialType, setSelectedMaterialType] = useState('') // 素材类型筛选,默认展示全部
|
const [selectedMaterialType, setSelectedMaterialType] = useState('') // 素材类型筛选,默认展示全部
|
||||||
// const [selectedMaterialType, setSelectedMaterialType] = useState('3D场景') // 素材类型筛选,默认展示3D场景(已注释,改为默认展示全部)
|
// const [selectedMaterialType, setSelectedMaterialType] = useState('3D场景') // 素材类型筛选,默认展示3D场景(已注释,改为默认展示全部)
|
||||||
const [selectedPlatform, setSelectedPlatform] = useState('') // 平台分类筛选
|
const [selectedPlatform, setSelectedPlatform] = useState('')
|
||||||
|
const [selectedLivePlatform, setSelectedLivePlatform] = useState('')
|
||||||
|
const [liveDateFrom, setLiveDateFrom] = useState('')
|
||||||
|
const [liveDateTo, setLiveDateTo] = useState('') // 平台分类筛选
|
||||||
const [selectedProductCategory, setSelectedProductCategory] = useState('') // 品类筛选
|
const [selectedProductCategory, setSelectedProductCategory] = useState('') // 品类筛选
|
||||||
const [categories, setCategories] = useState<FacetItem[]>([])
|
const [categories, setCategories] = useState<FacetItem[]>([])
|
||||||
const [scenes, setScenes] = useState<FacetItem[]>([])
|
const [scenes, setScenes] = useState<FacetItem[]>([])
|
||||||
@ -231,6 +234,9 @@ export default function MaterialLibraryPage() {
|
|||||||
if (selectedScene) params.append('scene', selectedScene)
|
if (selectedScene) params.append('scene', selectedScene)
|
||||||
if (selectedMaterialType) params.append('materialType', selectedMaterialType)
|
if (selectedMaterialType) params.append('materialType', selectedMaterialType)
|
||||||
if (selectedPlatform) params.append('platform', selectedPlatform)
|
if (selectedPlatform) params.append('platform', selectedPlatform)
|
||||||
|
if (selectedLivePlatform) params.append('livePlatform', selectedLivePlatform)
|
||||||
|
if (liveDateFrom) params.append('liveDateFrom', liveDateFrom)
|
||||||
|
if (liveDateTo) params.append('liveDateTo', liveDateTo)
|
||||||
if (selectedProductCategory) params.append('productCategory', selectedProductCategory)
|
if (selectedProductCategory) params.append('productCategory', selectedProductCategory)
|
||||||
if (selectedMonth) params.append('month', selectedMonth)
|
if (selectedMonth) params.append('month', selectedMonth)
|
||||||
if (includeSort) {
|
if (includeSort) {
|
||||||
@ -315,6 +321,9 @@ export default function MaterialLibraryPage() {
|
|||||||
if (selectedCategory) params.set('category', selectedCategory)
|
if (selectedCategory) params.set('category', selectedCategory)
|
||||||
if (selectedScene) params.set('scene', selectedScene)
|
if (selectedScene) params.set('scene', selectedScene)
|
||||||
if (selectedPlatform) params.set('platform', selectedPlatform)
|
if (selectedPlatform) params.set('platform', selectedPlatform)
|
||||||
|
if (selectedLivePlatform) params.set('livePlatform', selectedLivePlatform)
|
||||||
|
if (liveDateFrom) params.set('liveDateFrom', liveDateFrom)
|
||||||
|
if (liveDateTo) params.set('liveDateTo', liveDateTo)
|
||||||
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
||||||
if (selectedMonth) params.set('month', selectedMonth)
|
if (selectedMonth) params.set('month', selectedMonth)
|
||||||
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
||||||
@ -1386,6 +1395,12 @@ export default function MaterialLibraryPage() {
|
|||||||
setSelectedScene={setSelectedScene}
|
setSelectedScene={setSelectedScene}
|
||||||
selectedPlatform={selectedPlatform}
|
selectedPlatform={selectedPlatform}
|
||||||
setSelectedPlatform={setSelectedPlatform}
|
setSelectedPlatform={setSelectedPlatform}
|
||||||
|
selectedLivePlatform={selectedLivePlatform}
|
||||||
|
setSelectedLivePlatform={setSelectedLivePlatform}
|
||||||
|
liveDateFrom={liveDateFrom}
|
||||||
|
setLiveDateFrom={setLiveDateFrom}
|
||||||
|
liveDateTo={liveDateTo}
|
||||||
|
setLiveDateTo={setLiveDateTo}
|
||||||
selectedProductCategory={selectedProductCategory}
|
selectedProductCategory={selectedProductCategory}
|
||||||
setSelectedProductCategory={setSelectedProductCategory}
|
setSelectedProductCategory={setSelectedProductCategory}
|
||||||
selectedMonth={selectedMonth}
|
selectedMonth={selectedMonth}
|
||||||
|
|||||||
@ -120,6 +120,9 @@ export default function Home() {
|
|||||||
const [selectedMaterialType, setSelectedMaterialType] = useState('') // 素材类型筛选,默认展示全部
|
const [selectedMaterialType, setSelectedMaterialType] = useState('') // 素材类型筛选,默认展示全部
|
||||||
// const [selectedMaterialType, setSelectedMaterialType] = useState('3D场景') // 素材类型筛选,默认展示3D场景(已注释,改为默认展示全部)
|
// const [selectedMaterialType, setSelectedMaterialType] = useState('3D场景') // 素材类型筛选,默认展示3D场景(已注释,改为默认展示全部)
|
||||||
const [selectedPlatform, setSelectedPlatform] = useState('') // 平台分类筛选
|
const [selectedPlatform, setSelectedPlatform] = useState('') // 平台分类筛选
|
||||||
|
const [selectedLivePlatform, setSelectedLivePlatform] = useState('')
|
||||||
|
const [liveDateFrom, setLiveDateFrom] = useState('')
|
||||||
|
const [liveDateTo, setLiveDateTo] = useState('')
|
||||||
const [selectedProductCategory, setSelectedProductCategory] = useState('') // 品类筛选
|
const [selectedProductCategory, setSelectedProductCategory] = useState('') // 品类筛选
|
||||||
const [categories, setCategories] = useState<FacetItem[]>([])
|
const [categories, setCategories] = useState<FacetItem[]>([])
|
||||||
const [scenes, setScenes] = useState<FacetItem[]>([])
|
const [scenes, setScenes] = useState<FacetItem[]>([])
|
||||||
@ -205,6 +208,9 @@ export default function Home() {
|
|||||||
if (selectedScene) params.append('scene', selectedScene)
|
if (selectedScene) params.append('scene', selectedScene)
|
||||||
if (selectedMaterialType) params.append('materialType', selectedMaterialType)
|
if (selectedMaterialType) params.append('materialType', selectedMaterialType)
|
||||||
if (selectedPlatform) params.append('platform', selectedPlatform)
|
if (selectedPlatform) params.append('platform', selectedPlatform)
|
||||||
|
if (selectedLivePlatform) params.append('livePlatform', selectedLivePlatform)
|
||||||
|
if (liveDateFrom) params.append('liveDateFrom', liveDateFrom)
|
||||||
|
if (liveDateTo) params.append('liveDateTo', liveDateTo)
|
||||||
if (selectedProductCategory) params.append('productCategory', selectedProductCategory)
|
if (selectedProductCategory) params.append('productCategory', selectedProductCategory)
|
||||||
if (selectedMonth) params.append('month', selectedMonth)
|
if (selectedMonth) params.append('month', selectedMonth)
|
||||||
if (includeSort) {
|
if (includeSort) {
|
||||||
@ -287,6 +293,9 @@ export default function Home() {
|
|||||||
if (selectedCategory) params.set('category', selectedCategory)
|
if (selectedCategory) params.set('category', selectedCategory)
|
||||||
if (selectedScene) params.set('scene', selectedScene)
|
if (selectedScene) params.set('scene', selectedScene)
|
||||||
if (selectedPlatform) params.set('platform', selectedPlatform)
|
if (selectedPlatform) params.set('platform', selectedPlatform)
|
||||||
|
if (selectedLivePlatform) params.set('livePlatform', selectedLivePlatform)
|
||||||
|
if (liveDateFrom) params.set('liveDateFrom', liveDateFrom)
|
||||||
|
if (liveDateTo) params.set('liveDateTo', liveDateTo)
|
||||||
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
||||||
if (selectedMonth) params.set('month', selectedMonth)
|
if (selectedMonth) params.set('month', selectedMonth)
|
||||||
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
||||||
@ -1417,6 +1426,12 @@ export default function Home() {
|
|||||||
setSelectedScene={setSelectedScene}
|
setSelectedScene={setSelectedScene}
|
||||||
selectedPlatform={selectedPlatform}
|
selectedPlatform={selectedPlatform}
|
||||||
setSelectedPlatform={setSelectedPlatform}
|
setSelectedPlatform={setSelectedPlatform}
|
||||||
|
selectedLivePlatform={selectedLivePlatform}
|
||||||
|
setSelectedLivePlatform={setSelectedLivePlatform}
|
||||||
|
liveDateFrom={liveDateFrom}
|
||||||
|
setLiveDateFrom={setLiveDateFrom}
|
||||||
|
liveDateTo={liveDateTo}
|
||||||
|
setLiveDateTo={setLiveDateTo}
|
||||||
selectedProductCategory={selectedProductCategory}
|
selectedProductCategory={selectedProductCategory}
|
||||||
setSelectedProductCategory={setSelectedProductCategory}
|
setSelectedProductCategory={setSelectedProductCategory}
|
||||||
selectedMonth={selectedMonth}
|
selectedMonth={selectedMonth}
|
||||||
|
|||||||
@ -1044,6 +1044,23 @@ export default function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
|||||||
const handleBatchFilesUpload = async () => {
|
const handleBatchFilesUpload = async () => {
|
||||||
if (batchFiles.length === 0) return
|
if (batchFiles.length === 0) return
|
||||||
|
|
||||||
|
if (materialType === '直播切片') {
|
||||||
|
const missingTitle = batchFiles.some((item) => !item.productModel.trim())
|
||||||
|
if (missingTitle) {
|
||||||
|
setError('请为每个切片填写标题')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const liveErr: string[] = []
|
||||||
|
if (!liveDate.trim()) liveErr.push('请选择直播日期')
|
||||||
|
if (livePlatform.trim() && !['抖音', '快手', '视频号', '淘宝直播', 'B站'].includes(livePlatform.trim())) {
|
||||||
|
liveErr.push('请选择有效的直播平台')
|
||||||
|
}
|
||||||
|
if (liveErr.length > 0) {
|
||||||
|
setError(liveErr.join(';'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setUploading(true)
|
setUploading(true)
|
||||||
setIsProcessing(false)
|
setIsProcessing(false)
|
||||||
setUploadProgress(0)
|
setUploadProgress(0)
|
||||||
@ -1115,6 +1132,9 @@ export default function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
|||||||
: item.sceneName,
|
: item.sceneName,
|
||||||
platformName: item.platformName || '',
|
platformName: item.platformName || '',
|
||||||
productCategoryName: item.productCategoryName || '',
|
productCategoryName: item.productCategoryName || '',
|
||||||
|
...(materialType === '直播切片'
|
||||||
|
? { liveDate, liveHost, liveHostUserId, livePlatform }
|
||||||
|
: {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加渲染器(3D场景)
|
// 添加渲染器(3D场景)
|
||||||
@ -2653,7 +2673,7 @@ export default function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
|||||||
disabled={interactionLocked}
|
disabled={interactionLocked}
|
||||||
/>
|
/>
|
||||||
{/* 批量上传文件选择 */}
|
{/* 批量上传文件选择 */}
|
||||||
{!isTaskOtherMaterial && (materialType === '音乐' || isBatchVideoMaterialType(materialType) || materialType === '3D场景' || materialType === '品牌VI灵感') && (
|
{!isTaskOtherMaterial && (materialType === '音乐' || materialType === '直播切片' || isBatchVideoMaterialType(materialType) || materialType === '3D场景' || materialType === '品牌VI灵感') && (
|
||||||
<>
|
<>
|
||||||
<input
|
<input
|
||||||
ref={batchFileInputRef}
|
ref={batchFileInputRef}
|
||||||
@ -2671,7 +2691,8 @@ export default function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
|||||||
className={`${outlineButtonClass} mr-2`}
|
className={`${outlineButtonClass} mr-2`}
|
||||||
>
|
>
|
||||||
{materialType === '音乐' && '选择音乐文件(可多选)'}
|
{materialType === '音乐' && '选择音乐文件(可多选)'}
|
||||||
{isBatchVideoMaterialType(materialType) && '选择视频文件(可多选,最多8个)'}
|
{materialType === '直播切片' && '选择视频文件(可多选,最多20个)'}
|
||||||
|
{isBatchVideoMaterialType(materialType) && '选择视频文件(可多选,最多8个)'}
|
||||||
{materialType === '3D场景' && '选择3D文件或压缩包(可多选,最多5个)'}
|
{materialType === '3D场景' && '选择3D文件或压缩包(可多选,最多5个)'}
|
||||||
{materialType === '品牌VI灵感' && '选择PDF文件(可多选,最多50个)'}
|
{materialType === '品牌VI灵感' && '选择PDF文件(可多选,最多50个)'}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -32,6 +32,12 @@ interface FilterPanelProps {
|
|||||||
setSelectedScene: (value: string) => void
|
setSelectedScene: (value: string) => void
|
||||||
selectedPlatform: string
|
selectedPlatform: string
|
||||||
setSelectedPlatform: (value: string) => void
|
setSelectedPlatform: (value: string) => void
|
||||||
|
selectedLivePlatform?: string
|
||||||
|
setSelectedLivePlatform?: (value: string) => void
|
||||||
|
liveDateFrom?: string
|
||||||
|
setLiveDateFrom?: (value: string) => void
|
||||||
|
liveDateTo?: string
|
||||||
|
setLiveDateTo?: (value: string) => void
|
||||||
selectedProductCategory: string
|
selectedProductCategory: string
|
||||||
setSelectedProductCategory: (value: string) => void
|
setSelectedProductCategory: (value: string) => void
|
||||||
selectedMonth: string
|
selectedMonth: string
|
||||||
@ -61,6 +67,9 @@ function FilterPanel(props: FilterPanelProps) {
|
|||||||
selectedCategory, setSelectedCategory,
|
selectedCategory, setSelectedCategory,
|
||||||
selectedScene, setSelectedScene,
|
selectedScene, setSelectedScene,
|
||||||
selectedPlatform, setSelectedPlatform,
|
selectedPlatform, setSelectedPlatform,
|
||||||
|
selectedLivePlatform = '', setSelectedLivePlatform,
|
||||||
|
liveDateFrom = '', setLiveDateFrom,
|
||||||
|
liveDateTo = '', setLiveDateTo,
|
||||||
selectedProductCategory, setSelectedProductCategory,
|
selectedProductCategory, setSelectedProductCategory,
|
||||||
selectedMonth, setSelectedMonth,
|
selectedMonth, setSelectedMonth,
|
||||||
sortBy, setSortBy, sortOrder, setSortOrder,
|
sortBy, setSortBy, sortOrder, setSortOrder,
|
||||||
@ -328,6 +337,45 @@ function FilterPanel(props: FilterPanelProps) {
|
|||||||
{rankedPlatforms.map((item) => <button key={item.id} onClick={() => setSelectedPlatform(item.name === selectedPlatform ? '' : item.name)} className={`${chipBase} ${selectedPlatform === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
|
{rankedPlatforms.map((item) => <button key={item.id} onClick={() => setSelectedPlatform(item.name === selectedPlatform ? '' : item.name)} className={`${chipBase} ${selectedPlatform === item.name ? chipActive : chipInactive}`}>{item.name}<span className={`ml-1.5 ${countClass}`}>{countText(item.count || 0)}</span></button>)}
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
{setSelectedLivePlatform && (
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="mb-3 text-[13px] text-[#6b7075]">直播平台</h2>
|
||||||
|
<div className="flex flex-wrap gap-x-5 gap-y-2">
|
||||||
|
{['', '抖音', '快手', '视频号', '淘宝直播', 'B站'].map((name) => (
|
||||||
|
<button
|
||||||
|
key={name || 'all'}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setSelectedLivePlatform(name)}
|
||||||
|
className={`${chipBase} ${selectedLivePlatform === name ? chipActive : chipInactive}`}
|
||||||
|
>
|
||||||
|
{name || '全部'}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(setLiveDateFrom || setLiveDateTo) && (
|
||||||
|
<div className="mb-6">
|
||||||
|
<h2 className="mb-3 text-[13px] text-[#6b7075]">直播日期</h2>
|
||||||
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
aria-label="直播日期起"
|
||||||
|
value={liveDateFrom}
|
||||||
|
onChange={(e) => setLiveDateFrom?.(e.target.value)}
|
||||||
|
className={`${chipBase} cursor-text`}
|
||||||
|
/>
|
||||||
|
<span className="text-[12px] text-[#86898e]">至</span>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
aria-label="直播日期止"
|
||||||
|
value={liveDateTo}
|
||||||
|
onChange={(e) => setLiveDateTo?.(e.target.value)}
|
||||||
|
className={`${chipBase} cursor-text`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{(rankedProductCategories.length > 0 || facetsLoading) && <div className="mb-6">
|
{(rankedProductCategories.length > 0 || facetsLoading) && <div className="mb-6">
|
||||||
<h2 className="mb-3 text-[13px] text-[#6b7075]">产品类别</h2>
|
<h2 className="mb-3 text-[13px] text-[#6b7075]">产品类别</h2>
|
||||||
<div className="flex flex-wrap gap-x-5 gap-y-2">
|
<div className="flex flex-wrap gap-x-5 gap-y-2">
|
||||||
|
|||||||
@ -4,12 +4,14 @@ import { BATCH_LIMITS } from './upload-constants'
|
|||||||
import { isValidMainFileType, extractSpuFromFileName } from './upload-utils'
|
import { isValidMainFileType, extractSpuFromFileName } from './upload-utils'
|
||||||
import { requiresRenderer, shouldAutoFillGeneral } from '@/lib/material-validation'
|
import { requiresRenderer, shouldAutoFillGeneral } from '@/lib/material-validation'
|
||||||
import { isBatchVideoMaterialType } from '@/lib/video-material-types'
|
import { isBatchVideoMaterialType } from '@/lib/video-material-types'
|
||||||
|
import { isLiveClipType } from '@/lib/live-clip'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取批量上传限制
|
* 获取批量上传限制
|
||||||
*/
|
*/
|
||||||
export function getBatchLimit(materialType: string): number {
|
export function getBatchLimit(materialType: string): number {
|
||||||
if (materialType === '音乐') return BATCH_LIMITS.music
|
if (materialType === '音乐') return BATCH_LIMITS.music
|
||||||
|
if (isLiveClipType(materialType)) return 20
|
||||||
if (isBatchVideoMaterialType(materialType)) return BATCH_LIMITS.video
|
if (isBatchVideoMaterialType(materialType)) return BATCH_LIMITS.video
|
||||||
if (materialType === '3D场景') return BATCH_LIMITS['3d']
|
if (materialType === '3D场景') return BATCH_LIMITS['3d']
|
||||||
if (materialType === '品牌VI灵感') return BATCH_LIMITS.brandVI
|
if (materialType === '品牌VI灵感') return BATCH_LIMITS.brandVI
|
||||||
@ -28,9 +30,12 @@ export function createBatchFileItems(
|
|||||||
productCategoryName: string,
|
productCategoryName: string,
|
||||||
renderer: string
|
renderer: string
|
||||||
): BatchFileItem[] {
|
): BatchFileItem[] {
|
||||||
|
const isLiveClip = isLiveClipType(materialType)
|
||||||
return files.map((file, index) => {
|
return files.map((file, index) => {
|
||||||
const extractedSpu = extractSpuFromFileName(file.name)
|
const extractedSpu = isLiveClip
|
||||||
|
? file.name.replace(/\.[^.]+$/, '')
|
||||||
|
: extractSpuFromFileName(file.name)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: `${Date.now()}-${index}`,
|
id: `${Date.now()}-${index}`,
|
||||||
file,
|
file,
|
||||||
|
|||||||
@ -307,6 +307,10 @@ export async function completeBatchUpload(uploadId: string, metadata: Record<str
|
|||||||
formData.append('sceneName', metadata.sceneName || '通用')
|
formData.append('sceneName', metadata.sceneName || '通用')
|
||||||
formData.append('platformName', metadata.platformName || '')
|
formData.append('platformName', metadata.platformName || '')
|
||||||
formData.append('productCategoryName', metadata.productCategoryName || '')
|
formData.append('productCategoryName', metadata.productCategoryName || '')
|
||||||
|
if (metadata.liveDate) formData.append('liveDate', String(metadata.liveDate))
|
||||||
|
if (metadata.liveHost) formData.append('liveHost', String(metadata.liveHost))
|
||||||
|
if (metadata.liveHostUserId) formData.append('liveHostUserId', String(metadata.liveHostUserId))
|
||||||
|
if (metadata.livePlatform) formData.append('livePlatform', String(metadata.livePlatform))
|
||||||
const materialType = metadata.materialType || '3D场景'
|
const materialType = metadata.materialType || '3D场景'
|
||||||
formData.append('materialType', materialType)
|
formData.append('materialType', materialType)
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,12 @@ export interface UseHomeStateReturn {
|
|||||||
setSelectedMaterialType: React.Dispatch<React.SetStateAction<string>>
|
setSelectedMaterialType: React.Dispatch<React.SetStateAction<string>>
|
||||||
selectedPlatform: string
|
selectedPlatform: string
|
||||||
setSelectedPlatform: React.Dispatch<React.SetStateAction<string>>
|
setSelectedPlatform: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
selectedLivePlatform: string
|
||||||
|
setSelectedLivePlatform: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
liveDateFrom: string
|
||||||
|
setLiveDateFrom: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
liveDateTo: string
|
||||||
|
setLiveDateTo: React.Dispatch<React.SetStateAction<string>>
|
||||||
selectedProductCategory: string
|
selectedProductCategory: string
|
||||||
setSelectedProductCategory: React.Dispatch<React.SetStateAction<string>>
|
setSelectedProductCategory: React.Dispatch<React.SetStateAction<string>>
|
||||||
selectedMonth: string
|
selectedMonth: string
|
||||||
@ -149,6 +155,9 @@ export function useHomeState(): UseHomeStateReturn {
|
|||||||
const [selectedScene, setSelectedScene] = useState('')
|
const [selectedScene, setSelectedScene] = useState('')
|
||||||
const [selectedMaterialType, setSelectedMaterialType] = useState('')
|
const [selectedMaterialType, setSelectedMaterialType] = useState('')
|
||||||
const [selectedPlatform, setSelectedPlatform] = useState('')
|
const [selectedPlatform, setSelectedPlatform] = useState('')
|
||||||
|
const [selectedLivePlatform, setSelectedLivePlatform] = useState('')
|
||||||
|
const [liveDateFrom, setLiveDateFrom] = useState('')
|
||||||
|
const [liveDateTo, setLiveDateTo] = useState('')
|
||||||
const [selectedProductCategory, setSelectedProductCategory] = useState('')
|
const [selectedProductCategory, setSelectedProductCategory] = useState('')
|
||||||
const [selectedMonth, setSelectedMonth] = useState('')
|
const [selectedMonth, setSelectedMonth] = useState('')
|
||||||
|
|
||||||
@ -234,6 +243,9 @@ export function useHomeState(): UseHomeStateReturn {
|
|||||||
if (selectedCategory) params.set('category', selectedCategory)
|
if (selectedCategory) params.set('category', selectedCategory)
|
||||||
if (selectedScene) params.set('scene', selectedScene)
|
if (selectedScene) params.set('scene', selectedScene)
|
||||||
if (selectedPlatform) params.set('platform', selectedPlatform)
|
if (selectedPlatform) params.set('platform', selectedPlatform)
|
||||||
|
if (selectedLivePlatform) params.set('livePlatform', selectedLivePlatform)
|
||||||
|
if (liveDateFrom) params.set('liveDateFrom', liveDateFrom)
|
||||||
|
if (liveDateTo) params.set('liveDateTo', liveDateTo)
|
||||||
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
if (selectedProductCategory) params.set('productCategory', selectedProductCategory)
|
||||||
if (selectedMonth) params.set('month', selectedMonth)
|
if (selectedMonth) params.set('month', selectedMonth)
|
||||||
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
if (sortBy && sortBy !== 'createdAt') params.set('sortBy', sortBy)
|
||||||
@ -241,7 +253,7 @@ export function useHomeState(): UseHomeStateReturn {
|
|||||||
|
|
||||||
const newUrl = params.toString() ? `${window.location.pathname}?${params.toString()}` : window.location.pathname
|
const newUrl = params.toString() ? `${window.location.pathname}?${params.toString()}` : window.location.pathname
|
||||||
window.history.replaceState({}, '', newUrl)
|
window.history.replaceState({}, '', newUrl)
|
||||||
}, [searchKeyword, selectedMaterialType, selectedCategory, selectedScene, selectedPlatform, selectedProductCategory, selectedMonth, sortBy, sortOrder])
|
}, [searchKeyword, selectedMaterialType, selectedCategory, selectedScene, selectedPlatform, selectedLivePlatform, liveDateFrom, liveDateTo, selectedProductCategory, selectedMonth, sortBy, sortOrder])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// 素材数据
|
// 素材数据
|
||||||
@ -263,6 +275,12 @@ export function useHomeState(): UseHomeStateReturn {
|
|||||||
setSelectedMaterialType,
|
setSelectedMaterialType,
|
||||||
selectedPlatform,
|
selectedPlatform,
|
||||||
setSelectedPlatform,
|
setSelectedPlatform,
|
||||||
|
selectedLivePlatform,
|
||||||
|
setSelectedLivePlatform,
|
||||||
|
liveDateFrom,
|
||||||
|
setLiveDateFrom,
|
||||||
|
liveDateTo,
|
||||||
|
setLiveDateTo,
|
||||||
selectedProductCategory,
|
selectedProductCategory,
|
||||||
setSelectedProductCategory,
|
setSelectedProductCategory,
|
||||||
selectedMonth,
|
selectedMonth,
|
||||||
|
|||||||
@ -400,6 +400,10 @@ export async function buildMaterialWhereFromSearchParams(
|
|||||||
const materialType = searchParams.get('materialType') || ''
|
const materialType = searchParams.get('materialType') || ''
|
||||||
const platform = searchParams.get('platform') || ''
|
const platform = searchParams.get('platform') || ''
|
||||||
const productCategory = searchParams.get('productCategory') || ''
|
const productCategory = searchParams.get('productCategory') || ''
|
||||||
|
const livePlatform = searchParams.get('livePlatform') || ''
|
||||||
|
const liveDateFrom = searchParams.get('liveDateFrom') || ''
|
||||||
|
const liveDateTo = searchParams.get('liveDateTo') || ''
|
||||||
|
const liveHost = searchParams.get('liveHost') || ''
|
||||||
const month = searchParams.get('month') || ''
|
const month = searchParams.get('month') || ''
|
||||||
|
|
||||||
if (context.searchOrConditions) {
|
if (context.searchOrConditions) {
|
||||||
@ -415,6 +419,21 @@ export async function buildMaterialWhereFromSearchParams(
|
|||||||
if (platform && options.exclude !== 'platform') {
|
if (platform && options.exclude !== 'platform') {
|
||||||
where.platformName = platform
|
where.platformName = platform
|
||||||
}
|
}
|
||||||
|
if (livePlatform) {
|
||||||
|
where.livePlatform = livePlatform
|
||||||
|
}
|
||||||
|
if (liveHost) {
|
||||||
|
where.liveHost = { contains: liveHost, mode: 'insensitive' }
|
||||||
|
}
|
||||||
|
if (liveDateFrom || liveDateTo) {
|
||||||
|
where.liveDate = {}
|
||||||
|
if (liveDateFrom) {
|
||||||
|
where.liveDate.gte = new Date(`${liveDateFrom}T00:00:00.000Z`)
|
||||||
|
}
|
||||||
|
if (liveDateTo) {
|
||||||
|
where.liveDate.lte = new Date(`${liveDateTo}T23:59:59.999Z`)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (productCategory && options.exclude !== 'productCategory') {
|
if (productCategory && options.exclude !== 'productCategory') {
|
||||||
where.productCategoryName = productCategory
|
where.productCategoryName = productCategory
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
-- 直播切片:直播日期 / 主播 / 可选关联用户 / 直播平台
|
-- 直播切片:直播日期 / 主播 / 可选关联用户 / 直播平台
|
||||||
ALTER TABLE "Material" ADD COLUMN IF NOT EXISTS "live_date" TIMESTAMP(3);
|
ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "live_date" TIMESTAMP(3);
|
||||||
ALTER TABLE "Material" ADD COLUMN IF NOT EXISTS "live_host" TEXT;
|
ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "live_host" TEXT;
|
||||||
ALTER TABLE "Material" ADD COLUMN IF NOT EXISTS "live_host_user_id" TEXT;
|
ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "live_host_user_id" TEXT;
|
||||||
ALTER TABLE "Material" ADD COLUMN IF NOT EXISTS "live_platform" TEXT;
|
ALTER TABLE "materials" ADD COLUMN IF NOT EXISTS "live_platform" TEXT;
|
||||||
CREATE INDEX IF NOT EXISTS "Material_live_date_idx" ON "Material"("live_date");
|
CREATE INDEX IF NOT EXISTS "materials_live_date_idx" ON "materials"("live_date");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user