feat(plan): 添加计划书列表 Mock 数据支持
- 新增 mockPlanListAPI 函数支持分页、状态筛选、关键词搜索 - 集成 Mock 数据开关,开发环境自动启用 - 支持测试分页加载、状态筛选、关键词搜索、查看功能 - 数据结构完全符合 API 文档规范
Showing
2 changed files
with
160 additions
and
3 deletions
| ... | @@ -137,10 +137,14 @@ import { ref, nextTick } from 'vue' | ... | @@ -137,10 +137,14 @@ import { ref, nextTick } from 'vue' |
| 137 | import Taro, { useLoad, useReachBottom } from '@tarojs/taro' | 137 | import Taro, { useLoad, useReachBottom } from '@tarojs/taro' |
| 138 | import { useFileOperation } from '@/composables/useFileOperation' | 138 | import { useFileOperation } from '@/composables/useFileOperation' |
| 139 | import { listAPI, viewAPI, deleteAPI } from '@/api/plan' | 139 | import { listAPI, viewAPI, deleteAPI } from '@/api/plan' |
| 140 | +import { mockPlanListAPI } from '@/utils/mockData' | ||
| 140 | import NavHeader from '@/components/navigation/NavHeader.vue' | 141 | import NavHeader from '@/components/navigation/NavHeader.vue' |
| 141 | import ListItemActions from '@/components/list/ListItemActions/index.vue' | 142 | import ListItemActions from '@/components/list/ListItemActions/index.vue' |
| 142 | import SearchBar from '@/components/forms/SearchBar.vue' | 143 | import SearchBar from '@/components/forms/SearchBar.vue' |
| 143 | 144 | ||
| 145 | +// Mock 数据开关(开发环境使用 Mock,生产环境使用真实 API) | ||
| 146 | +const USE_MOCK_DATA = process.env.NODE_ENV === 'development' | ||
| 147 | + | ||
| 144 | const { viewFile } = useFileOperation() | 148 | const { viewFile } = useFileOperation() |
| 145 | 149 | ||
| 146 | const searchValue = ref('') | 150 | const searchValue = ref('') |
| ... | @@ -244,7 +248,7 @@ const transformApiItem = (apiItem) => { | ... | @@ -244,7 +248,7 @@ const transformApiItem = (apiItem) => { |
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | /** | 250 | /** |
| 247 | - * 加载计划书列表(调用真实 API) | 251 | + * 加载计划书列表(支持 Mock 数据) |
| 248 | * @param {number} page - 页码(从0开始,API 要求) | 252 | * @param {number} page - 页码(从0开始,API 要求) |
| 249 | * @param {number} limit - 每页数量 | 253 | * @param {number} limit - 每页数量 |
| 250 | * @param {boolean} isLoadMore - 是否为加载更多 | 254 | * @param {boolean} isLoadMore - 是否为加载更多 |
| ... | @@ -271,6 +275,10 @@ const transformApiItem = (apiItem) => { | ... | @@ -271,6 +275,10 @@ const transformApiItem = (apiItem) => { |
| 271 | * - "5" = 处理中 | 275 | * - "5" = 处理中 |
| 272 | * - "7" = 已生成 | 276 | * - "7" = 已生成 |
| 273 | * - "9" = 已查看 | 277 | * - "9" = 已查看 |
| 278 | + * | ||
| 279 | + * 🔧 **Mock 数据说明**: | ||
| 280 | + * 开发环境会使用 Mock 数据测试分页、筛选、搜索功能 | ||
| 281 | + * 生产环境使用真实 API | ||
| 274 | */ | 282 | */ |
| 275 | const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => { | 283 | const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => { |
| 276 | try { | 284 | try { |
| ... | @@ -297,8 +305,10 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => | ... | @@ -297,8 +305,10 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => |
| 297 | params.keyword = searchValue.value | 305 | params.keyword = searchValue.value |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | - // 调用 API | 308 | + // 🔧 根据环境选择使用 Mock 数据还是真实 API |
| 301 | - const res = await listAPI(params) | 309 | + const res = USE_MOCK_DATA |
| 310 | + ? await mockPlanListAPI(params) | ||
| 311 | + : await listAPI(params) | ||
| 302 | 312 | ||
| 303 | if (res.code === 1 && res.data) { | 313 | if (res.code === 1 && res.data) { |
| 304 | let apiList = res.data.list || [] | 314 | let apiList = res.data.list || [] | ... | ... |
| ... | @@ -10,6 +10,7 @@ | ... | @@ -10,6 +10,7 @@ |
| 10 | * - myListAPI: 消息列表 | 10 | * - myListAPI: 消息列表 |
| 11 | * - favoriteListAPI: 收藏列表 | 11 | * - favoriteListAPI: 收藏列表 |
| 12 | * - feedbackListAPI: 意见反馈列表 | 12 | * - feedbackListAPI: 意见反馈列表 |
| 13 | + * - planListAPI: 计划书列表(新增) | ||
| 13 | */ | 14 | */ |
| 14 | 15 | ||
| 15 | // ============================================================================ | 16 | // ============================================================================ |
| ... | @@ -769,6 +770,150 @@ export async function mockFeedbackListAPI(params) { | ... | @@ -769,6 +770,150 @@ export async function mockFeedbackListAPI(params) { |
| 769 | } | 770 | } |
| 770 | 771 | ||
| 771 | // ============================================================================ | 772 | // ============================================================================ |
| 773 | +// 8. 计划书列表 Mock (planListAPI) | ||
| 774 | +// ============================================================================ | ||
| 775 | + | ||
| 776 | +const PLAN_PRODUCT_NAMES = [ | ||
| 777 | + '终身寿险至尊版', | ||
| 778 | + '重疾险保障计划', | ||
| 779 | + '百万年金保险计划', | ||
| 780 | + '高端医疗险', | ||
| 781 | + '养老理财保险', | ||
| 782 | + '教育金保险计划', | ||
| 783 | + '意外伤害保险', | ||
| 784 | + '定期寿险', | ||
| 785 | + '终身寿险', | ||
| 786 | + '企业年金保险', | ||
| 787 | + '团体意外险', | ||
| 788 | + '健康保险计划' | ||
| 789 | +] | ||
| 790 | + | ||
| 791 | +const PLAN_STATUS = ['3', '5', '7', '9'] // 3=待处理, 5=处理中, 7=已生成, 9=已查看 | ||
| 792 | + | ||
| 793 | +const PLAN_CATEGORIES = [ | ||
| 794 | + { id: '1', name: '人寿保险' }, | ||
| 795 | + { id: '2', name: '重疾险' }, | ||
| 796 | + { id: '3', name: '医疗险' }, | ||
| 797 | + { id: '4', name: '年金险' }, | ||
| 798 | + { id: '5', name: '意外险' } | ||
| 799 | +] | ||
| 800 | + | ||
| 801 | +const CUSTOMER_NAMES = [ | ||
| 802 | + '张三', '李四', '王五', '赵六', '钱七', | ||
| 803 | + '孙八', '周九', '吴十', '郑十一', '陈十二', | ||
| 804 | + '刘十三', '黄十四', '杨十五', '朱十六', '胡十七' | ||
| 805 | +] | ||
| 806 | + | ||
| 807 | +/** | ||
| 808 | + * 生成计划书列表项 | ||
| 809 | + * @param {number} id - 计划书ID | ||
| 810 | + * @returns {Object} 计划书对象 | ||
| 811 | + */ | ||
| 812 | +function generatePlanItem(id) { | ||
| 813 | + const productName = PLAN_PRODUCT_NAMES[Math.floor(Math.random() * PLAN_PRODUCT_NAMES.length)] | ||
| 814 | + const customerName = CUSTOMER_NAMES[Math.floor(Math.random() * CUSTOMER_NAMES.length)] | ||
| 815 | + const orderStatus = PLAN_STATUS[Math.floor(Math.random() * PLAN_STATUS.length)] | ||
| 816 | + const category = PLAN_CATEGORIES[Math.floor(Math.random() * PLAN_CATEGORIES.length)] | ||
| 817 | + | ||
| 818 | + // 生成创建时间(最近30天内) | ||
| 819 | + const now = new Date() | ||
| 820 | + const createTime = new Date(now.getTime() - Math.random() * 30 * 24 * 60 * 60 * 1000) | ||
| 821 | + | ||
| 822 | + // 根据状态决定是否有计划书文件 | ||
| 823 | + const hasFiles = orderStatus === '7' || orderStatus === '9' // 已生成或已查看才有文件 | ||
| 824 | + const proposalFiles = [] | ||
| 825 | + | ||
| 826 | + if (hasFiles) { | ||
| 827 | + // 生成1-3个计划书文件 | ||
| 828 | + const fileCount = Math.floor(Math.random() * 3) + 1 | ||
| 829 | + for (let i = 0; i < fileCount; i++) { | ||
| 830 | + proposalFiles.push({ | ||
| 831 | + id: id * 10 + i, | ||
| 832 | + file_name: `${customerName}-${productName}-计划书.pdf`, | ||
| 833 | + file_url: `https://picsum.photos/seed/plan-${id}-${i}/400/300` | ||
| 834 | + }) | ||
| 835 | + } | ||
| 836 | + } | ||
| 837 | + | ||
| 838 | + return { | ||
| 839 | + id: id, | ||
| 840 | + customer_name: customerName, | ||
| 841 | + product_name: productName, | ||
| 842 | + categories: [category], | ||
| 843 | + created_time: formatDate(createTime), | ||
| 844 | + order_status: orderStatus, | ||
| 845 | + proposal_files: proposalFiles | ||
| 846 | + } | ||
| 847 | +} | ||
| 848 | + | ||
| 849 | +/** | ||
| 850 | + * Mock: planListAPI (计划书列表) | ||
| 851 | + * @description 支持分页、状态筛选、关键词搜索 | ||
| 852 | + * @param {Object} params - 请求参数 | ||
| 853 | + * @param {number} params.page - 页码(从0开始) | ||
| 854 | + * @param {number} params.limit - 每页数量(默认20) | ||
| 855 | + * @param {string} [params.status] - 状态筛选(3=待处理, 5=处理中, 7=已生成, 9=已查看) | ||
| 856 | + * @param {string} [params.keyword] - 搜索关键字 | ||
| 857 | + * @returns {Promise<Object>} Mock 响应 | ||
| 858 | + */ | ||
| 859 | +export async function mockPlanListAPI(params) { | ||
| 860 | + await mockDelay() | ||
| 861 | + | ||
| 862 | + const { page = 0, limit = 20, status, keyword } = params | ||
| 863 | + const totalPages = 10 | ||
| 864 | + | ||
| 865 | + // 如果超过总页数,返回空列表 | ||
| 866 | + if (page >= totalPages) { | ||
| 867 | + console.log(`[Mock] planListAPI - 第${page}页,共0条(已到最后一页)`) | ||
| 868 | + return { | ||
| 869 | + code: 1, | ||
| 870 | + msg: 'success', | ||
| 871 | + data: { | ||
| 872 | + list: [], | ||
| 873 | + total: totalPages * limit | ||
| 874 | + } | ||
| 875 | + } | ||
| 876 | + } | ||
| 877 | + | ||
| 878 | + const list = [] | ||
| 879 | + const startIndex = page * limit | ||
| 880 | + | ||
| 881 | + // 生成数据并过滤 | ||
| 882 | + for (let i = 0; i < limit; i++) { | ||
| 883 | + const item = generatePlanItem(startIndex + i + 1) | ||
| 884 | + | ||
| 885 | + // 状态筛选 | ||
| 886 | + if (status && item.order_status !== status) { | ||
| 887 | + continue | ||
| 888 | + } | ||
| 889 | + | ||
| 890 | + // 关键词搜索(搜索产品名或客户名) | ||
| 891 | + if (keyword) { | ||
| 892 | + const searchKeyword = keyword.toLowerCase() | ||
| 893 | + const productName = item.product_name.toLowerCase() | ||
| 894 | + const customerName = item.customer_name.toLowerCase() | ||
| 895 | + | ||
| 896 | + if (!productName.includes(searchKeyword) && !customerName.includes(searchKeyword)) { | ||
| 897 | + continue | ||
| 898 | + } | ||
| 899 | + } | ||
| 900 | + | ||
| 901 | + list.push(item) | ||
| 902 | + } | ||
| 903 | + | ||
| 904 | + console.log(`[Mock] planListAPI - 第${page}页,共${list.length}条,状态筛选:${status || '无'},关键词:"${keyword || '无'}"`) | ||
| 905 | + | ||
| 906 | + return { | ||
| 907 | + code: 1, | ||
| 908 | + msg: 'success', | ||
| 909 | + data: { | ||
| 910 | + list, | ||
| 911 | + total: totalPages * limit | ||
| 912 | + } | ||
| 913 | + } | ||
| 914 | +} | ||
| 915 | + | ||
| 916 | +// ============================================================================ | ||
| 772 | // 导出统一 Mock API 调用器 | 917 | // 导出统一 Mock API 调用器 |
| 773 | // ============================================================================ | 918 | // ============================================================================ |
| 774 | 919 | ||
| ... | @@ -794,6 +939,8 @@ export async function mockAPI(apiName, params) { | ... | @@ -794,6 +939,8 @@ export async function mockAPI(apiName, params) { |
| 794 | return await mockFavoriteListAPI(params) | 939 | return await mockFavoriteListAPI(params) |
| 795 | case 'feedbackListAPI': | 940 | case 'feedbackListAPI': |
| 796 | return await mockFeedbackListAPI(params) | 941 | return await mockFeedbackListAPI(params) |
| 942 | + case 'planListAPI': | ||
| 943 | + return await mockPlanListAPI(params) | ||
| 797 | default: | 944 | default: |
| 798 | console.warn(`[Mock] 未知的 API: ${apiName}`) | 945 | console.warn(`[Mock] 未知的 API: ${apiName}`) |
| 799 | return { code: 0, msg: 'Unknown API', data: null } | 946 | return { code: 0, msg: 'Unknown API', data: null } | ... | ... |
-
Please register or login to post a comment