index.vue 8.43 KB
<template>
  <view class="h-screen bg-gray-50 flex flex-col">
    <view class="bg-gray-50">
      <!-- Navigation Header -->
      <NavHeader title="我的计划书" />

      <!-- Search Bar -->
      <view class="bg-white px-[24rpx] py-[16rpx]">
        <nut-searchbar v-model="searchValue" placeholder="搜索计划书名称、客户姓名..." @search="onSearch" clearable>
          <template #left-in>
            <IconFont name="search" size="14" />
          </template>
        </nut-searchbar>
      </view>

      <!-- Tabs -->
      <view class="bg-white mt-[2rpx] px-[24rpx] py-[20rpx]">
        <FilterTabs v-model="activeTab" :tabs="tabs" label-key="title" />
      </view>
    </view>

    <!-- Plan List -->
    <view class="flex-1 overflow-y-auto px-[24rpx] py-[24rpx] pb-[200rpx]">
      <view v-for="(item, index) in filteredList" :key="index"
        class="bg-white rounded-[24rpx] p-[24rpx] mb-[24rpx] shadow-sm">
        <!-- Header -->
        <view class="flex justify-between items-start mb-[16rpx]">
          <view class="flex-1">
            <view class="text-[30rpx] font-bold text-gray-900 leading-normal mb-[8rpx]">{{ item.title }}</view>
            <view class="flex items-center gap-[12rpx]">
              <view class="bg-blue-50 text-blue-600 text-[22rpx] px-[12rpx] py-[4rpx] rounded-[8rpx]" v-if="item.tag">
                {{ item.tag }}
              </view>
            </view>
          </view>
          <view class="ml-[24rpx]">
            <!-- Status Badge or Icon could go here -->
          </view>
        </view>

        <!-- Info -->
        <view class="flex justify-between items-center text-gray-500 text-[24rpx] mb-[24rpx]">
          <text>{{ item.client }}</text>
          <text>{{ item.date }}</text>
        </view>

        <!-- Divider -->
        <view class="h-[1rpx] bg-gray-100 my-[20rpx]"></view>

        <!-- Actions -->
        <ListItemActions
          :viewable="true"
          :deletable="true"
          @view="onView(item)"
          @delete="onDelete(item)"
        />
      </view>

      <!-- Empty State -->
      <view v-if="filteredList.length === 0"
        class="flex flex-col items-center justify-center py-[100rpx] text-gray-400">
        <IconFont name="order" size="48" class="mb-[24rpx] opacity-50" />
        <text class="text-[28rpx]">暂无相关计划书</text>
      </view>
    </view>

    <!-- TabBar -->
    <!-- <TabBar current="" /> -->
  </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useGo } from '@/hooks/useGo'
import { useFileOperation } from '@/composables/useFileOperation'
import IconFont from '@/components/IconFont.vue'
import FilterTabs from '@/components/FilterTabs.vue'
import NavHeader from '@/components/NavHeader.vue'
import ListItemActions from '@/components/ListItemActions/index.vue'
import Taro from '@tarojs/taro'

const go = useGo()
const { viewFile } = useFileOperation()

const searchValue = ref('')
const activeTab = ref(0)
const tabs = [
  { title: '全部', key: 'all' },
  { title: '生成中', key: 'processing' },
  { title: '已生成', key: 'generated' }
]

/**
 * Mock 数据:计划书列表
 *
 * @description 使用真实 PDF 文件进行测试
 * downloadUrl 使用 Mozilla 的公开 PDF 测试文件
 */
const list = ref([
  {
    id: 1,
    title: '家庭财富传承保障计划(分红)',
    client: '客户:李*生',
    date: '2024-03-15 10:12',
    tag: '年金保险',
    status: 'generated',
    // 文档信息
    fileName: '家庭财富传承保障计划(分红).pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 2,
    title: '财富传承保障金融理财计划(分红)',
    client: '客户:孙*',
    date: '2024-03-14 12:01',
    tag: '',
    status: 'processing',
    // 生成中的文档没有下载地址
    fileName: '',
    downloadUrl: ''
  },
  {
    id: 3,
    title: '企业高管年金计划',
    client: '客户:王*江',
    date: '2024-03-13 09:23',
    tag: '年金保险',
    status: 'generated',
    // 文档信息
    fileName: '企业高管年金计划.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 4,
    title: '家庭财富传承保障计划',
    client: '客户:李*生',
    date: '2024-03-12 15:12',
    tag: '年金保险',
    status: 'generated',
    // 文档信息
    fileName: '家庭财富传承保障计划.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 5,
    title: '高净值家庭资产配置计划',
    client: '客户:赵*琪',
    date: '2024-03-11 18:40',
    tag: '资产配置',
    status: 'generated',
    fileName: '高净值家庭资产配置计划.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 6,
    title: '企业主税务筹划方案',
    client: '客户:陈*明',
    date: '2024-03-11 11:05',
    tag: '税务筹划',
    status: 'processing',
    fileName: '',
    downloadUrl: ''
  },
  {
    id: 7,
    title: '家庭保障升级计划(重疾)',
    client: '客户:周*然',
    date: '2024-03-10 14:22',
    tag: '健康保障',
    status: 'generated',
    fileName: '家庭保障升级计划(重疾).pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 8,
    title: '家庭教育金规划方案',
    client: '客户:许*雅',
    date: '2024-03-10 09:48',
    tag: '教育金',
    status: 'generated',
    fileName: '家庭教育金规划方案.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 9,
    title: '中长期养老规划',
    client: '客户:刘*文',
    date: '2024-03-09 16:05',
    tag: '养老规划',
    status: 'processing',
    fileName: '',
    downloadUrl: ''
  },
  {
    id: 10,
    title: '企业员工福利保障计划',
    client: '客户:沈*杰',
    date: '2024-03-09 10:33',
    tag: '团体保障',
    status: 'generated',
    fileName: '企业员工福利保障计划.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 11,
    title: '家族信托规划方案',
    client: '客户:唐*豪',
    date: '2024-03-08 17:50',
    tag: '家族信托',
    status: 'generated',
    fileName: '家族信托规划方案.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  },
  {
    id: 12,
    title: '企业接班人保障方案',
    client: '客户:何*峰',
    date: '2024-03-08 09:12',
    tag: '传承保障',
    status: 'generated',
    fileName: '企业接班人保障方案.pdf',
    downloadUrl: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'
  }
])

/**
 * 根据标签页和搜索关键词过滤列表
 */
const filteredList = computed(() => {
  let result = list.value

  // Filter by Tab
  const currentKey = tabs[activeTab.value].key
  if (currentKey !== 'all') {
    result = result.filter(item => item.status === currentKey)
  }

  // Filter by Search
  if (searchValue.value) {
    const key = searchValue.value.toLowerCase()
    result = result.filter(item =>
      item.title.toLowerCase().includes(key) ||
      item.client.toLowerCase().includes(key)
    )
  }

  return result
})

/**
 * 搜索处理
 */
const onSearch = (val) => {
  console.log('Search:', val)
}

/**
 * 查看计划书文档
 *
 * @description 使用 useFileOperation 的 viewFile 功能查看 PDF 文档
 * @param {Object} item - 计划书对象
 */
const onView = async (item) => {
  // 检查是否已生成
  if (item.status === 'processing') {
    Taro.showToast({
      title: '计划书生成中,请稍后',
      icon: 'none'
    })
    return
  }

  // 使用 useFileOperation 查看文档
  await viewFile({
    downloadUrl: item.downloadUrl,
    fileName: item.fileName
  })
}

/**
 * 删除计划书
 */
const onDelete = (item) => {
  Taro.showModal({
    title: '提示',
    content: '确定要删除该计划书吗?',
    success: (res) => {
      if (res.confirm) {
        list.value = list.value.filter(i => i.id !== item.id)
        Taro.showToast({ title: '已删除', icon: 'success' })
      }
    }
  })
}
</script>