forked from wangziqi/gongxue-base
feat: add taro student learning flow
This commit is contained in:
3
apps/taro/src/pages/student/assets/index.config.ts
Normal file
3
apps/taro/src/pages/student/assets/index.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '资料',
|
||||
});
|
||||
70
apps/taro/src/pages/student/assets/index.tsx
Normal file
70
apps/taro/src/pages/student/assets/index.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { Button, Text, View } from '@tarojs/components';
|
||||
import { loadContentAssets, signAssetDownload, signAssetPreview, type ContentAsset } from '@/services/catalog';
|
||||
import '../student.css';
|
||||
|
||||
function openUrl(url?: string) {
|
||||
if (!url) return;
|
||||
if (process.env.TARO_ENV === 'h5' && typeof window !== 'undefined') {
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
return;
|
||||
}
|
||||
Taro.setClipboardData({ data: url });
|
||||
}
|
||||
|
||||
export default function StudentAssetsPage() {
|
||||
const [assets, setAssets] = useState<ContentAsset[]>([]);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
loadContentAssets({ includeLocked: true })
|
||||
.then(payload => setAssets(payload.items || []))
|
||||
.catch(nextError => setError(nextError instanceof Error ? nextError.message : '资料加载失败'));
|
||||
}, []);
|
||||
|
||||
async function preview(asset: ContentAsset) {
|
||||
try {
|
||||
const payload = await signAssetPreview(asset.id);
|
||||
openUrl(payload.preview?.url);
|
||||
} catch (nextError) {
|
||||
setError(nextError instanceof Error ? nextError.message : '预览失败');
|
||||
}
|
||||
}
|
||||
|
||||
async function download(asset: ContentAsset) {
|
||||
try {
|
||||
const payload = await signAssetDownload(asset.id);
|
||||
openUrl(payload.download?.url);
|
||||
} catch (nextError) {
|
||||
setError(nextError instanceof Error ? nextError.message : '下载失败');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='student-page'>
|
||||
<View className='student-topbar'>
|
||||
<View className='student-title-block'>
|
||||
<Text className='student-kicker'>Assets</Text>
|
||||
<Text className='student-title'>资料下载</Text>
|
||||
<Text className='student-subtitle'>私有文件必须向后端申请短期签名,前端不直接拼对象存储地址。</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className='list-stack'>
|
||||
{assets.map(item => (
|
||||
<View className='list-row' key={item.id}>
|
||||
<Text className='row-main'>{item.title || item.fileName || '未命名资料'}</Text>
|
||||
<Text className='row-meta'>{item.assetType || 'asset'} · {item.visibility || 'public'}</Text>
|
||||
{item.description ? <Text className='row-meta'>{item.description}</Text> : null}
|
||||
<View className='toolbar'>
|
||||
<Button className='secondary-button' onClick={() => preview(item)}>预览</Button>
|
||||
<Button className='primary-button' onClick={() => download(item)}>下载</Button>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
{!assets.length ? <View className='empty-state'>暂无可见资料。</View> : null}
|
||||
{error ? <Text className='error-text'>{error}</Text> : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user