<template>
  <XtfConfigProvider class="demo-theme-root" :theme="demoTheme" component-size="md" :safe-area="true">
    <scroll-view class="upload-demo-scroll xtf-page-scroll" direction="vertical">
      <view class="upload-demo-page xtf-page-scroll-content">
        <view class="upload-demo-hero"><text class="upload-demo-kicker">XTF LINKUI / COMPONENTS</text><text class="upload-demo-title">Upload</text><text class="upload-demo-intro">原生媒体选择、队列并发、取消、重试与手动提交。</text></view>
        <view class="upload-demo-section"><text class="upload-demo-heading">自动队列</text><text class="upload-demo-copy">本地模拟上传，最多同时处理两个文件；卡片内可取消，失败后点击重试。</text><XtfUpload ref="automaticUpload" v-model="images" :max="3" :concurrent="2" :custom-request="customRequest" @progress="progress" @success="success" @error="error" @cancel="cancel" /></view>
        <view class="upload-demo-section"><text class="upload-demo-heading">手动提交</text><text class="upload-demo-copy">选择文件后处于 ready 状态，点击按钮再加入上传队列。</text><XtfUpload ref="manualUpload" v-model="videos" file-type="video" :multiple="false" :auto-upload="false" /><XtfButton class="upload-demo-submit" label="提交视频队列" size="sm" @click="submit" /></view>
        <view class="upload-demo-section"><text class="upload-demo-heading">自定义请求</text><text class="upload-demo-copy">将 action、headers、formData 与回调交给业务上传适配器。本例以本地模拟回调演示。</text><XtfUpload v-model="customFiles" :max="2" :mock-upload="false" :custom-request="customRequest" @success="customSuccess" /></view>
        <view class="upload-demo-section"><text class="upload-demo-heading">队列操作</text><XtfButton id="upload-demo-retry" label="重试失败文件" @click="retryAll" /><XtfButton id="upload-demo-clear" label="清空上传列表" type="outline" @click="clearAll" /><XtfButton id="upload-demo-seed" label="载入本地模拟队列" type="outline" @click="seedMock" /><XtfButton id="upload-demo-start" label="启动模拟队列" @click="automaticUpload?.submit()" /><XtfButton id="upload-demo-cancel-all" label="取消全部" type="outline" @click="automaticUpload?.cancelAllUpload()" /><text class="upload-demo-copy">模拟队列仅使用本地图片；第二项首次失败，重试后成功，不发送网络请求。</text><text class="upload-demo-state">{{ status }}</text><text class="upload-demo-count">已完成 {{ images.filter(file => file.status == 'success').length }} / {{ images.length }}</text></view>
      </view>
    </scroll-view>
  </XtfConfigProvider>
</template>
<script setup lang="uts">
import { useDemoTheme } from '@/pages/demo-theme.uts'
const demoTheme = useDemoTheme()
import XtfConfigProvider from "@/uni_modules/xtf-linkuiunix/components/xtf-config-provider/xtf-config-provider.uvue"
import XtfButton from "@/uni_modules/xtf-linkuiunix/components/xtf-button/xtf-button.uvue"
import { nextTick, ref } from "vue"
import XtfUpload from "@/uni_modules/xtf-linkuiunix/components/xtf-upload/xtf-upload.uvue"
const images = ref([] as Array<any>)
const videos = ref([] as Array<any>)
const customFiles = ref([] as Array<any>)
const manualUpload = ref<any>(null)
const automaticUpload = ref<any>(null)
const status = ref("等待选择")
function progress(payload: any): void { status.value = "上传中 " + payload.progress.toString() + "%" }
function success(): void { status.value = "上传完成" }
function error(payload: any): void { status.value = "上传失败: " + payload.file.errorText }
function cancel(): void { status.value = "上传已取消" }
function submit(): void { manualUpload.value?.submit(); status.value = "视频队列已提交" }
function customSuccess(): void { status.value = "自定义请求完成" }
function retryAll(): void { const count = automaticUpload.value?.retryFailed() || 0; status.value = "已加入重试队列: " + count }
function clearAll(): void { automaticUpload.value?.clearFiles(); status.value = "上传列表已清空" }
const mockAttempts = {} as UTSJSONObject
async function seedMock(): Promise<void> { automaticUpload.value?.clearFiles(); await nextTick(); images.value = [{ id: 'local-a', url: '/static/logo.png', name: '本地成功示例', type: 'image', status: 'ready', progress: 0 }, { id: 'local-b', url: '/static/logo.png', name: '本地失败后重试示例', type: 'image', status: 'ready', progress: 0 }]; mockAttempts['local-b'] = 0; status.value = '已载入本地模拟队列，点击启动' }
function customRequest(options: any): any { let progress = 0; const id = options.file.id as string; const failOnce = id == 'local-b' && Number(mockAttempts[id] || 0) == 0; mockAttempts[id] = Number(mockAttempts[id] || 0) + 1; const timer = setInterval((): void => { progress += 25; options.onProgress(progress); if (progress >= 100) { clearInterval(timer); if (failOnce) options.onError({ errMsg: '本地模拟失败，请重试' }); else options.onSuccess({ url: options.file.url, simulated: true }) } }, 160); return { abort: (): void => { clearInterval(timer) } } }
</script>
<style>
.upload-demo-scroll { display: flex; flex-direction: column; flex: 1; width: 100%; height: 100%; }.upload-demo-page { display: flex; flex-direction: column; width: 100%; padding: 24rpx; background-color: var(--xtf-color-page, #f8fafc); }.upload-demo-hero { display: flex; flex-direction: column; padding: 32rpx; border-radius: 16rpx; background-color: #c2410c; }.upload-demo-kicker, .upload-demo-intro { color: #ffffff; font-size: 22rpx; }.upload-demo-title { margin-top: 8rpx; color: #ffffff; font-size: 52rpx; font-weight: 700; }.upload-demo-intro { margin-top: 12rpx; }.upload-demo-section { display: flex; flex-direction: column; margin-top: 24rpx; padding: 24rpx; border-radius: 16rpx; background-color: var(--xtf-color-surface, #ffffff); }.upload-demo-heading { margin-bottom: 12rpx; color: var(--xtf-color-text, #172033); font-size: 30rpx; font-weight: 700; }.upload-demo-copy { margin-bottom: 20rpx; color: var(--xtf-color-text-secondary, #64748b); font-size: 22rpx; line-height: 1.45; }.upload-demo-submit { margin-top: 16rpx; }.upload-demo-state { color: var(--xtf-color-text-secondary, #475569); font-size: 24rpx; }
</style>
