feat(plan): 新增驳回工单支持并展示驳回理由
新增订单驳回状态常量与映射配置,调整计划书查看权限逻辑以允许访问带文件的驳回工单,新增列表页驳回理由展示与交互组件,同步更新API文档、类型定义、模拟数据及测试用例。
Showing
7 changed files
with
205 additions
and
13 deletions
| ... | @@ -54,7 +54,7 @@ export const deleteAPI = (params) => fn(fetch.post(Api.Delete, params)); | ... | @@ -54,7 +54,7 @@ export const deleteAPI = (params) => fn(fetch.post(Api.Delete, params)); |
| 54 | * @description 计划书列表 | 54 | * @description 计划书列表 |
| 55 | * @remark | 55 | * @remark |
| 56 | * @param {Object} params 请求参数 | 56 | * @param {Object} params 请求参数 |
| 57 | - * @param {string} params.status (可选) 3:待处理,5:处理中,7:已生成,9:已查看 | 57 | + * @param {string} params.status (可选) 3:待处理,5:处理中,7:已生成,9:已查看,11:驳回 |
| 58 | * @param {string} params.keyword (可选) | 58 | * @param {string} params.keyword (可选) |
| 59 | * @param {string} params.limit (可选) | 59 | * @param {string} params.limit (可选) |
| 60 | * @param {string} params.page (可选) | 60 | * @param {string} params.page (可选) |
| ... | @@ -72,6 +72,7 @@ export const deleteAPI = (params) => fn(fetch.post(Api.Delete, params)); | ... | @@ -72,6 +72,7 @@ export const deleteAPI = (params) => fn(fetch.post(Api.Delete, params)); |
| 72 | }>; | 72 | }>; |
| 73 | created_time: string; // 创建时间 | 73 | created_time: string; // 创建时间 |
| 74 | order_status: string; // 状态 | 74 | order_status: string; // 状态 |
| 75 | + reject_reason?: string; // 驳回理由 | ||
| 75 | proposal_files: Array<{ | 76 | proposal_files: Array<{ |
| 76 | file_name: string; // 名称 | 77 | file_name: string; // 名称 |
| 77 | file_url: string; // 地址 | 78 | file_url: string; // 地址 | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2026-02-13 01:05:52 | 2 | * @Date: 2026-02-13 01:05:52 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2026-02-27 13:17:37 | 4 | + * @LastEditTime: 2026-05-28 14:35:04 |
| 5 | * @FilePath: /manulife-weapp/src/config/app.js | 5 | * @FilePath: /manulife-weapp/src/config/app.js |
| 6 | * @Description: 应用配置 | 6 | * @Description: 应用配置 |
| 7 | */ | 7 | */ | ... | ... |
| ... | @@ -28,7 +28,9 @@ export const ORDER_STATUS = { | ... | @@ -28,7 +28,9 @@ export const ORDER_STATUS = { |
| 28 | /** 已生成 - 对应 API 值 '7' */ | 28 | /** 已生成 - 对应 API 值 '7' */ |
| 29 | GENERATED: '7', | 29 | GENERATED: '7', |
| 30 | /** 已查看 - 对应 API 值 '9' */ | 30 | /** 已查看 - 对应 API 值 '9' */ |
| 31 | - VIEWED: '9' | 31 | + VIEWED: '9', |
| 32 | + /** 已驳回 - 对应 API 值 '11' */ | ||
| 33 | + REJECTED: '11' | ||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | /** | 36 | /** |
| ... | @@ -41,7 +43,8 @@ export const ORDER_STATUS_MAP = { | ... | @@ -41,7 +43,8 @@ export const ORDER_STATUS_MAP = { |
| 41 | [ORDER_STATUS.PENDING]: 'pending', | 43 | [ORDER_STATUS.PENDING]: 'pending', |
| 42 | [ORDER_STATUS.PROCESSING]: 'processing', | 44 | [ORDER_STATUS.PROCESSING]: 'processing', |
| 43 | [ORDER_STATUS.GENERATED]: 'generated', | 45 | [ORDER_STATUS.GENERATED]: 'generated', |
| 44 | - [ORDER_STATUS.VIEWED]: 'viewed' | 46 | + [ORDER_STATUS.VIEWED]: 'viewed', |
| 47 | + [ORDER_STATUS.REJECTED]: 'rejected' | ||
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | /** | 50 | /** |
| ... | @@ -54,7 +57,8 @@ export const ORDER_STATUS_TEXT = { | ... | @@ -54,7 +57,8 @@ export const ORDER_STATUS_TEXT = { |
| 54 | pending: '待处理', | 57 | pending: '待处理', |
| 55 | processing: '处理中', | 58 | processing: '处理中', |
| 56 | generated: '已生成', | 59 | generated: '已生成', |
| 57 | - viewed: '已查看' | 60 | + viewed: '已查看', |
| 61 | + rejected: '驳回' | ||
| 58 | } | 62 | } |
| 59 | 63 | ||
| 60 | /** | 64 | /** | ... | ... |
| ... | @@ -82,7 +82,8 @@ | ... | @@ -82,7 +82,8 @@ |
| 82 | item.status === 'pending' ? 'status-pending' : '', | 82 | item.status === 'pending' ? 'status-pending' : '', |
| 83 | item.status === 'processing' ? 'status-processing' : '', | 83 | item.status === 'processing' ? 'status-processing' : '', |
| 84 | item.status === 'generated' ? 'status-generated' : '', | 84 | item.status === 'generated' ? 'status-generated' : '', |
| 85 | - item.status === 'viewed' ? 'status-viewed' : '' | 85 | + item.status === 'viewed' ? 'status-viewed' : '', |
| 86 | + item.status === 'rejected' ? 'status-rejected' : '' | ||
| 86 | ]" | 87 | ]" |
| 87 | > | 88 | > |
| 88 | {{ getStatusText(item.status) }} | 89 | {{ getStatusText(item.status) }} |
| ... | @@ -91,9 +92,53 @@ | ... | @@ -91,9 +92,53 @@ |
| 91 | </view> | 92 | </view> |
| 92 | 93 | ||
| 93 | <!-- Info --> | 94 | <!-- Info --> |
| 94 | - <view class="flex justify-between items-center text-gray-500 text-[24rpx] mb-[24rpx]"> | 95 | + <view class="text-gray-500 text-[24rpx] mb-[24rpx]"> |
| 95 | - <text>{{ item.client }}</text> | 96 | + <view class="flex justify-between items-center gap-[24rpx]"> |
| 96 | - <text>{{ item.date }}</text> | 97 | + <text>{{ item.client }}</text> |
| 98 | + <text class="shrink-0">{{ item.date }}</text> | ||
| 99 | + </view> | ||
| 100 | + <view | ||
| 101 | + v-if="item.status === 'rejected' && item.rejectReason" | ||
| 102 | + class="reject-reason-box relative mt-[16rpx] rounded-[16rpx] px-[20rpx] py-[16rpx]" | ||
| 103 | + > | ||
| 104 | + <text class="reject-reason-label text-[22rpx] font-medium">驳回理由</text> | ||
| 105 | + <view | ||
| 106 | + v-if="!item.rejectReasonExpanded" | ||
| 107 | + class="reject-reason-text relative mt-[8rpx] text-[24rpx] leading-[1.6]" | ||
| 108 | + > | ||
| 109 | + <view | ||
| 110 | + :class="[ | ||
| 111 | + 'break-all', | ||
| 112 | + item.rejectReasonOverflow ? 'reject-reason-clamp reject-reason-content-with-expand' : '' | ||
| 113 | + ]" | ||
| 114 | + > | ||
| 115 | + {{ item.rejectReason }} | ||
| 116 | + </view> | ||
| 117 | + <text | ||
| 118 | + v-if="item.rejectReasonOverflow" | ||
| 119 | + class="reject-reason-expand reject-reason-action font-medium" | ||
| 120 | + @tap.stop="toggleRejectReason(item)" | ||
| 121 | + > | ||
| 122 | + 展开 | ||
| 123 | + </text> | ||
| 124 | + <view | ||
| 125 | + :id="getRejectMeasureId(item.id)" | ||
| 126 | + class="reject-reason-measure reject-reason-content-with-expand break-all" | ||
| 127 | + > | ||
| 128 | + {{ item.rejectReason }} | ||
| 129 | + </view> | ||
| 130 | + </view> | ||
| 131 | + <view v-else class="reject-reason-text mt-[8rpx] text-[24rpx] leading-[1.6] break-all"> | ||
| 132 | + <text>{{ item.rejectReason }}</text> | ||
| 133 | + <text | ||
| 134 | + v-if="item.rejectReasonOverflow" | ||
| 135 | + class="reject-reason-action ml-[8rpx] font-medium" | ||
| 136 | + @tap.stop="toggleRejectReason(item)" | ||
| 137 | + > | ||
| 138 | + 收起 | ||
| 139 | + </text> | ||
| 140 | + </view> | ||
| 141 | + </view> | ||
| 97 | </view> | 142 | </view> |
| 98 | 143 | ||
| 99 | <!-- Divider --> | 144 | <!-- Divider --> |
| ... | @@ -160,6 +205,8 @@ const hasMore = ref(true) | ... | @@ -160,6 +205,8 @@ const hasMore = ref(true) |
| 160 | const currentList = ref([]) | 205 | const currentList = ref([]) |
| 161 | const currentPage = ref(0) // 当前页码(从0开始) | 206 | const currentPage = ref(0) // 当前页码(从0开始) |
| 162 | const pageSize = 20 // 每页数量 | 207 | const pageSize = 20 // 每页数量 |
| 208 | +const REJECT_REASON_MAX_LINES = 2 | ||
| 209 | +const REJECT_REASON_LINE_HEIGHT_RPX = 24 * 1.6 | ||
| 163 | 210 | ||
| 164 | /** | 211 | /** |
| 165 | * Tab 数据源 | 212 | * Tab 数据源 |
| ... | @@ -170,6 +217,7 @@ const pageSize = 20 // 每页数量 | ... | @@ -170,6 +217,7 @@ const pageSize = 20 // 每页数量 |
| 170 | * - "5" = 处理中 | 217 | * - "5" = 处理中 |
| 171 | * - "7" = 已生成 | 218 | * - "7" = 已生成 |
| 172 | * - "9" = 已查看 | 219 | * - "9" = 已查看 |
| 220 | + * - "11" = 驳回 | ||
| 173 | */ | 221 | */ |
| 174 | const tabsData = ref([ | 222 | const tabsData = ref([ |
| 175 | { id: '', name: '全部', list: [] }, | 223 | { id: '', name: '全部', list: [] }, |
| ... | @@ -204,6 +252,9 @@ const transformApiItem = (apiItem) => { | ... | @@ -204,6 +252,9 @@ const transformApiItem = (apiItem) => { |
| 204 | date: apiItem.created_time || '', | 252 | date: apiItem.created_time || '', |
| 205 | tag: categoryName, | 253 | tag: categoryName, |
| 206 | status: mapOrderStatus(apiItem.order_status), | 254 | status: mapOrderStatus(apiItem.order_status), |
| 255 | + rejectReason: apiItem.reject_reason || '', | ||
| 256 | + rejectReasonExpanded: false, | ||
| 257 | + rejectReasonOverflow: false, | ||
| 207 | // 默认显示第一个文件 | 258 | // 默认显示第一个文件 |
| 208 | fileName: firstFile?.file_name || '', | 259 | fileName: firstFile?.file_name || '', |
| 209 | downloadUrl: firstFile?.file_url || '', | 260 | downloadUrl: firstFile?.file_url || '', |
| ... | @@ -226,6 +277,7 @@ const transformApiItem = (apiItem) => { | ... | @@ -226,6 +277,7 @@ const transformApiItem = (apiItem) => { |
| 226 | * - activeTabId = '5':只显示处理中的计划书 | 277 | * - activeTabId = '5':只显示处理中的计划书 |
| 227 | * - activeTabId = '7':只显示已生成的计划书 | 278 | * - activeTabId = '7':只显示已生成的计划书 |
| 228 | * - activeTabId = '9':只显示已查看的计划书 | 279 | * - activeTabId = '9':只显示已查看的计划书 |
| 280 | + * - activeTabId = '11':只显示驳回的计划书(当前页面暂未提供单独 Tab) | ||
| 229 | * | 281 | * |
| 230 | * ✅ **API参数说明**: | 282 | * ✅ **API参数说明**: |
| 231 | * ```javascript | 283 | * ```javascript |
| ... | @@ -242,6 +294,7 @@ const transformApiItem = (apiItem) => { | ... | @@ -242,6 +294,7 @@ const transformApiItem = (apiItem) => { |
| 242 | * - "5" = 处理中 | 294 | * - "5" = 处理中 |
| 243 | * - "7" = 已生成 | 295 | * - "7" = 已生成 |
| 244 | * - "9" = 已查看 | 296 | * - "9" = 已查看 |
| 297 | + * - "11" = 驳回 | ||
| 245 | * | 298 | * |
| 246 | * 🔧 **Mock 数据说明**: | 299 | * 🔧 **Mock 数据说明**: |
| 247 | * 开发环境会使用 Mock 数据测试分页、筛选、搜索功能 | 300 | * 开发环境会使用 Mock 数据测试分页、筛选、搜索功能 |
| ... | @@ -289,6 +342,8 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => | ... | @@ -289,6 +342,8 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => |
| 289 | currentList.value = transformedList | 342 | currentList.value = transformedList |
| 290 | } | 343 | } |
| 291 | 344 | ||
| 345 | + await measureRejectReasonOverflow() | ||
| 346 | + | ||
| 292 | // 判断是否还有更多数据 | 347 | // 判断是否还有更多数据 |
| 293 | // 如果返回的数据量少于请求的量,说明没有更多了 | 348 | // 如果返回的数据量少于请求的量,说明没有更多了 |
| 294 | hasMore.value = transformedList.length >= limit | 349 | hasMore.value = transformedList.length >= limit |
| ... | @@ -316,6 +371,60 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => | ... | @@ -316,6 +371,60 @@ const fetchPlanList = async (page = 0, limit = pageSize, isLoadMore = false) => |
| 316 | } | 371 | } |
| 317 | 372 | ||
| 318 | /** | 373 | /** |
| 374 | + * 将 rpx 转为 px,便于与节点测量结果比较。 | ||
| 375 | + * @param {number} rpx - 设计稿 rpx 数值 | ||
| 376 | + * @returns {number} 转换后的 px 数值 | ||
| 377 | + */ | ||
| 378 | +const rpxToPx = (rpx) => { | ||
| 379 | + const { windowWidth = 375 } = Taro.getSystemInfoSync() | ||
| 380 | + return (windowWidth / 750) * rpx | ||
| 381 | +} | ||
| 382 | + | ||
| 383 | +/** | ||
| 384 | + * 生成驳回理由隐藏测量节点 ID。 | ||
| 385 | + * @param {string|number} itemId - 列表项 ID | ||
| 386 | + * @returns {string} 节点 ID | ||
| 387 | + */ | ||
| 388 | +const getRejectMeasureId = (itemId) => `reject-reason-measure-${itemId}` | ||
| 389 | + | ||
| 390 | +/** | ||
| 391 | + * 计算驳回理由是否超过两行。 | ||
| 392 | + * @description 列表页使用隐藏节点测量真实高度,只在超出两行时显示展开入口。 | ||
| 393 | + */ | ||
| 394 | +const measureRejectReasonOverflow = async () => { | ||
| 395 | + const rejectedItems = currentList.value.filter(item => item.status === 'rejected' && item.rejectReason) | ||
| 396 | + | ||
| 397 | + if (rejectedItems.length === 0) { | ||
| 398 | + return | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + await nextTick() | ||
| 402 | + | ||
| 403 | + const maxHeight = rpxToPx(REJECT_REASON_LINE_HEIGHT_RPX * REJECT_REASON_MAX_LINES) + 1 | ||
| 404 | + const query = Taro.createSelectorQuery() | ||
| 405 | + | ||
| 406 | + rejectedItems.forEach((item) => { | ||
| 407 | + query.select(`#${getRejectMeasureId(item.id)}`).boundingClientRect() | ||
| 408 | + }) | ||
| 409 | + | ||
| 410 | + query.exec((rects = []) => { | ||
| 411 | + rects.forEach((rect, index) => { | ||
| 412 | + const item = rejectedItems[index] | ||
| 413 | + | ||
| 414 | + if (!item) { | ||
| 415 | + return | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + item.rejectReasonOverflow = Boolean(rect && rect.height > maxHeight) | ||
| 419 | + | ||
| 420 | + if (!item.rejectReasonOverflow) { | ||
| 421 | + item.rejectReasonExpanded = false | ||
| 422 | + } | ||
| 423 | + }) | ||
| 424 | + }) | ||
| 425 | +} | ||
| 426 | + | ||
| 427 | +/** | ||
| 319 | * Tab 点击处理 | 428 | * Tab 点击处理 |
| 320 | */ | 429 | */ |
| 321 | const onTabClick = (id) => { | 430 | const onTabClick = (id) => { |
| ... | @@ -491,6 +600,14 @@ const onDelete = async (item) => { | ... | @@ -491,6 +600,14 @@ const onDelete = async (item) => { |
| 491 | } | 600 | } |
| 492 | }) | 601 | }) |
| 493 | } | 602 | } |
| 603 | + | ||
| 604 | +/** | ||
| 605 | + * 切换驳回理由展开状态 | ||
| 606 | + * @param {Object} item - 计划书对象 | ||
| 607 | + */ | ||
| 608 | +const toggleRejectReason = (item) => { | ||
| 609 | + item.rejectReasonExpanded = !item.rejectReasonExpanded | ||
| 610 | +} | ||
| 494 | </script> | 611 | </script> |
| 495 | 612 | ||
| 496 | <style lang="less"> | 613 | <style lang="less"> |
| ... | @@ -623,4 +740,56 @@ const onDelete = async (item) => { | ... | @@ -623,4 +740,56 @@ const onDelete = async (item) => { |
| 623 | background-color: #E5E7EB; | 740 | background-color: #E5E7EB; |
| 624 | color: #6B7280; | 741 | color: #6B7280; |
| 625 | } | 742 | } |
| 743 | + | ||
| 744 | +.status-rejected { | ||
| 745 | + background-color: #FEE2E2; | ||
| 746 | + color: #DC2626; | ||
| 747 | +} | ||
| 748 | + | ||
| 749 | +.reject-reason-box { | ||
| 750 | + background-color: #F8F4EE; | ||
| 751 | +} | ||
| 752 | + | ||
| 753 | +.reject-reason-label { | ||
| 754 | + color: #8B6B4A; | ||
| 755 | +} | ||
| 756 | + | ||
| 757 | +.reject-reason-text { | ||
| 758 | + color: #5F5A54; | ||
| 759 | +} | ||
| 760 | + | ||
| 761 | +.reject-reason-action { | ||
| 762 | + color: #8A735C; | ||
| 763 | +} | ||
| 764 | + | ||
| 765 | +.reject-reason-clamp { | ||
| 766 | + display: -webkit-box; | ||
| 767 | + overflow: hidden; | ||
| 768 | + -webkit-box-orient: vertical; | ||
| 769 | + -webkit-line-clamp: 2; | ||
| 770 | + line-clamp: 2; | ||
| 771 | +} | ||
| 772 | + | ||
| 773 | +.reject-reason-content-with-expand { | ||
| 774 | + padding-right: 124rpx; | ||
| 775 | +} | ||
| 776 | + | ||
| 777 | +.reject-reason-expand { | ||
| 778 | + position: absolute; | ||
| 779 | + right: 0; | ||
| 780 | + bottom: 0; | ||
| 781 | + padding-left: 36rpx; | ||
| 782 | + line-height: inherit; | ||
| 783 | + background: linear-gradient(90deg, rgba(248, 244, 238, 0) 0%, #F8F4EE 30%, #F8F4EE 100%); | ||
| 784 | +} | ||
| 785 | + | ||
| 786 | +.reject-reason-measure { | ||
| 787 | + position: absolute; | ||
| 788 | + left: 0; | ||
| 789 | + right: 0; | ||
| 790 | + top: 0; | ||
| 791 | + visibility: hidden; | ||
| 792 | + pointer-events: none; | ||
| 793 | + z-index: -1; | ||
| 794 | +} | ||
| 626 | </style> | 795 | </style> | ... | ... |
| ... | @@ -23,6 +23,13 @@ describe('proposalView', () => { | ... | @@ -23,6 +23,13 @@ describe('proposalView', () => { |
| 23 | })).toBe(false) | 23 | })).toBe(false) |
| 24 | }) | 24 | }) |
| 25 | 25 | ||
| 26 | + it('驳回且有文件时应该允许查看', () => { | ||
| 27 | + expect(canViewProposal({ | ||
| 28 | + order_status: '11', | ||
| 29 | + proposal_files: [{ file_name: '计划书.pdf', file_url: 'https://example.com/plan.pdf' }] | ||
| 30 | + })).toBe(true) | ||
| 31 | + }) | ||
| 32 | + | ||
| 26 | it('应该兼容 proposalFiles 字段', () => { | 33 | it('应该兼容 proposalFiles 字段', () => { |
| 27 | const files = [{ file_name: '计划书.pdf', file_url: 'https://example.com/plan.pdf' }] | 34 | const files = [{ file_name: '计划书.pdf', file_url: 'https://example.com/plan.pdf' }] |
| 28 | 35 | ... | ... |
| ... | @@ -1067,7 +1067,14 @@ const PLAN_PRODUCT_NAMES = [ | ... | @@ -1067,7 +1067,14 @@ const PLAN_PRODUCT_NAMES = [ |
| 1067 | '健康保险计划' | 1067 | '健康保险计划' |
| 1068 | ] | 1068 | ] |
| 1069 | 1069 | ||
| 1070 | -const PLAN_STATUS = ['3', '5', '7', '9'] // 3=待处理, 5=处理中, 7=已生成, 9=已查看 | 1070 | +const PLAN_STATUS = ['3', '5', '7', '9', '11'] // 3=待处理, 5=处理中, 7=已生成, 9=已查看, 11=驳回 |
| 1071 | + | ||
| 1072 | +const PLAN_REJECT_REASONS = [ | ||
| 1073 | + '客户资料填写不完整,请补充完整的身份证明文件后重新提交。', | ||
| 1074 | + '方案参数与当前产品投保规则不符,请调整缴费年期与提取设置。', | ||
| 1075 | + '系统审核发现申请人与产品适配性不足,建议重新评估保障需求后再生成计划书。', | ||
| 1076 | + '关键资料缺失,暂无法继续生成计划书,请补充健康告知及财务证明信息。', | ||
| 1077 | +] | ||
| 1071 | 1078 | ||
| 1072 | const PLAN_CATEGORIES = [ | 1079 | const PLAN_CATEGORIES = [ |
| 1073 | { id: '1', name: '人寿保险' }, | 1080 | { id: '1', name: '人寿保险' }, |
| ... | @@ -1093,6 +1100,9 @@ function generatePlanItem(id) { | ... | @@ -1093,6 +1100,9 @@ function generatePlanItem(id) { |
| 1093 | const customerName = CUSTOMER_NAMES[Math.floor(Math.random() * CUSTOMER_NAMES.length)] | 1100 | const customerName = CUSTOMER_NAMES[Math.floor(Math.random() * CUSTOMER_NAMES.length)] |
| 1094 | const orderStatus = PLAN_STATUS[Math.floor(Math.random() * PLAN_STATUS.length)] | 1101 | const orderStatus = PLAN_STATUS[Math.floor(Math.random() * PLAN_STATUS.length)] |
| 1095 | const category = PLAN_CATEGORIES[Math.floor(Math.random() * PLAN_CATEGORIES.length)] | 1102 | const category = PLAN_CATEGORIES[Math.floor(Math.random() * PLAN_CATEGORIES.length)] |
| 1103 | + const rejectReason = orderStatus === '11' | ||
| 1104 | + ? PLAN_REJECT_REASONS[Math.floor(Math.random() * PLAN_REJECT_REASONS.length)] | ||
| 1105 | + : '' | ||
| 1096 | 1106 | ||
| 1097 | // 生成创建时间(最近30天内) | 1107 | // 生成创建时间(最近30天内) |
| 1098 | const now = new Date() | 1108 | const now = new Date() |
| ... | @@ -1122,6 +1132,7 @@ function generatePlanItem(id) { | ... | @@ -1122,6 +1132,7 @@ function generatePlanItem(id) { |
| 1122 | categories: [category], | 1132 | categories: [category], |
| 1123 | created_time: formatDate(createTime), | 1133 | created_time: formatDate(createTime), |
| 1124 | order_status: orderStatus, | 1134 | order_status: orderStatus, |
| 1135 | + reject_reason: rejectReason, | ||
| 1125 | proposal_files: proposalFiles | 1136 | proposal_files: proposalFiles |
| 1126 | } | 1137 | } |
| 1127 | } | 1138 | } |
| ... | @@ -1132,7 +1143,7 @@ function generatePlanItem(id) { | ... | @@ -1132,7 +1143,7 @@ function generatePlanItem(id) { |
| 1132 | * @param {Object} params - 请求参数 | 1143 | * @param {Object} params - 请求参数 |
| 1133 | * @param {number} params.page - 页码(从0开始) | 1144 | * @param {number} params.page - 页码(从0开始) |
| 1134 | * @param {number} params.limit - 每页数量(默认20) | 1145 | * @param {number} params.limit - 每页数量(默认20) |
| 1135 | - * @param {string} [params.status] - 状态筛选(3=待处理, 5=处理中, 7=已生成, 9=已查看) | 1146 | + * @param {string} [params.status] - 状态筛选(3=待处理, 5=处理中, 7=已生成, 9=已查看, 11=驳回) |
| 1136 | * @param {string} [params.keyword] - 搜索关键字 | 1147 | * @param {string} [params.keyword] - 搜索关键字 |
| 1137 | * @returns {Promise<Object>} Mock 响应 | 1148 | * @returns {Promise<Object>} Mock 响应 |
| 1138 | */ | 1149 | */ | ... | ... |
| ... | @@ -37,7 +37,7 @@ export const getProposalFiles = (proposal = {}) => { | ... | @@ -37,7 +37,7 @@ export const getProposalFiles = (proposal = {}) => { |
| 37 | * | 37 | * |
| 38 | * 当前业务规则: | 38 | * 当前业务规则: |
| 39 | * - 待处理不可查看 | 39 | * - 待处理不可查看 |
| 40 | - * - 处理中/已生成/已查看,只要存在文件就允许查看 | 40 | + * - 只要存在文件,除待处理外都允许查看 |
| 41 | */ | 41 | */ |
| 42 | export const canViewProposal = (proposal = {}) => { | 42 | export const canViewProposal = (proposal = {}) => { |
| 43 | const status = getProposalStatus(proposal) | 43 | const status = getProposalStatus(proposal) |
| ... | @@ -47,5 +47,5 @@ export const canViewProposal = (proposal = {}) => { | ... | @@ -47,5 +47,5 @@ export const canViewProposal = (proposal = {}) => { |
| 47 | return false | 47 | return false |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | - return status === 'processing' || status === 'generated' || status === 'viewed' | 50 | + return status !== 'pending' |
| 51 | } | 51 | } | ... | ... |
-
Please register or login to post a comment