feat(news): 支持消息列表后端 title 字段
- 消息列表页优先使用 API 返回的 title 字段 - 保留 getItemTitle 作为降级方案 - 更新 API 文档以反映 title 字段 - 同步更新消息详情页
Showing
6 changed files
with
124 additions
and
13 deletions
| ... | @@ -75,17 +75,81 @@ paths: | ... | @@ -75,17 +75,81 @@ paths: |
| 75 | pk_id: | 75 | pk_id: |
| 76 | type: integer | 76 | type: integer |
| 77 | title: 计划书订单ID | 77 | title: 计划书订单ID |
| 78 | + proposal: | ||
| 79 | + type: object | ||
| 80 | + properties: | ||
| 81 | + id: | ||
| 82 | + type: integer | ||
| 83 | + customer_name: | ||
| 84 | + type: string | ||
| 85 | + title: 申请人 | ||
| 86 | + product_name: | ||
| 87 | + type: string | ||
| 88 | + title: 产品名 | ||
| 89 | + categories: | ||
| 90 | + type: array | ||
| 91 | + items: | ||
| 92 | + type: object | ||
| 93 | + properties: | ||
| 94 | + id: | ||
| 95 | + type: string | ||
| 96 | + title: 分类id | ||
| 97 | + name: | ||
| 98 | + type: string | ||
| 99 | + title: 分类名 | ||
| 100 | + x-apifox-orders: | ||
| 101 | + - id | ||
| 102 | + - name | ||
| 103 | + title: 分类 | ||
| 104 | + created_time: | ||
| 105 | + type: string | ||
| 106 | + title: 创建时间 | ||
| 107 | + order_status: | ||
| 108 | + type: string | ||
| 109 | + title: 状态 | ||
| 110 | + proposal_files: | ||
| 111 | + type: array | ||
| 112 | + items: | ||
| 113 | + type: object | ||
| 114 | + properties: | ||
| 115 | + file_name: | ||
| 116 | + type: string | ||
| 117 | + title: 名称 | ||
| 118 | + file_url: | ||
| 119 | + type: string | ||
| 120 | + title: 地址 | ||
| 121 | + id: | ||
| 122 | + type: integer | ||
| 123 | + required: | ||
| 124 | + - file_name | ||
| 125 | + - file_url | ||
| 126 | + x-apifox-orders: | ||
| 127 | + - id | ||
| 128 | + - file_url | ||
| 129 | + - file_name | ||
| 130 | + title: 生成的计划书 | ||
| 131 | + x-apifox-orders: | ||
| 132 | + - id | ||
| 133 | + - customer_name | ||
| 134 | + - product_name | ||
| 135 | + - created_time | ||
| 136 | + - order_status | ||
| 137 | + - categories | ||
| 138 | + - proposal_files | ||
| 139 | + title: 计划书订单 | ||
| 78 | x-apifox-orders: | 140 | x-apifox-orders: |
| 79 | - id | 141 | - id |
| 80 | - note | 142 | - note |
| 81 | - created_time | 143 | - created_time |
| 82 | - status | 144 | - status |
| 83 | - pk_id | 145 | - pk_id |
| 146 | + - proposal | ||
| 84 | required: | 147 | required: |
| 85 | - note | 148 | - note |
| 86 | - created_time | 149 | - created_time |
| 87 | - status | 150 | - status |
| 88 | - pk_id | 151 | - pk_id |
| 152 | + - proposal | ||
| 89 | required: | 153 | required: |
| 90 | - code | 154 | - code |
| 91 | - msg | 155 | - msg | ... | ... |
| ... | @@ -87,17 +87,22 @@ paths: | ... | @@ -87,17 +87,22 @@ paths: |
| 87 | pk_id: | 87 | pk_id: |
| 88 | type: integer | 88 | type: integer |
| 89 | title: 计划书订单ID | 89 | title: 计划书订单ID |
| 90 | + title: | ||
| 91 | + type: string | ||
| 92 | + title: 标题 | ||
| 90 | x-apifox-orders: | 93 | x-apifox-orders: |
| 91 | - id | 94 | - id |
| 92 | - note | 95 | - note |
| 93 | - created_time | 96 | - created_time |
| 94 | - status | 97 | - status |
| 95 | - pk_id | 98 | - pk_id |
| 99 | + - title | ||
| 96 | required: | 100 | required: |
| 97 | - note | 101 | - note |
| 98 | - created_time | 102 | - created_time |
| 99 | - status | 103 | - status |
| 100 | - pk_id | 104 | - pk_id |
| 105 | + - title | ||
| 101 | total: | 106 | total: |
| 102 | type: integer | 107 | type: integer |
| 103 | x-apifox-orders: | 108 | x-apifox-orders: | ... | ... |
| ... | @@ -19,6 +19,22 @@ const Api = { | ... | @@ -19,6 +19,22 @@ const Api = { |
| 19 | created_time: string; // 发消息的时间 | 19 | created_time: string; // 发消息的时间 |
| 20 | status: string; // send=以发送未读取,read=已读取 | 20 | status: string; // send=以发送未读取,read=已读取 |
| 21 | pk_id: integer; // 计划书订单ID | 21 | pk_id: integer; // 计划书订单ID |
| 22 | + proposal: { | ||
| 23 | + id: integer; // | ||
| 24 | + customer_name: string; // 申请人 | ||
| 25 | + product_name: string; // 产品名 | ||
| 26 | + categories: Array<{ | ||
| 27 | + id: string; // 分类id | ||
| 28 | + name: string; // 分类名 | ||
| 29 | + }>; | ||
| 30 | + created_time: string; // 创建时间 | ||
| 31 | + order_status: string; // 状态 | ||
| 32 | + proposal_files: Array<{ | ||
| 33 | + file_name: string; // 名称 | ||
| 34 | + file_url: string; // 地址 | ||
| 35 | + id: integer; // | ||
| 36 | + }>; | ||
| 37 | + }; | ||
| 22 | * }; | 38 | * }; |
| 23 | * }>} | 39 | * }>} |
| 24 | */ | 40 | */ |
| ... | @@ -40,6 +56,7 @@ export const detailAPI = (params) => fn(fetch.get(Api.Detail, params)); | ... | @@ -40,6 +56,7 @@ export const detailAPI = (params) => fn(fetch.get(Api.Detail, params)); |
| 40 | created_time: string; // 发消息的时间 | 56 | created_time: string; // 发消息的时间 |
| 41 | status: string; // send=以发送未读取,read=已读取 | 57 | status: string; // send=以发送未读取,read=已读取 |
| 42 | pk_id: integer; // 计划书订单ID | 58 | pk_id: integer; // 计划书订单ID |
| 59 | + title: string; // 标题 | ||
| 43 | }>; | 60 | }>; |
| 44 | total: integer; // | 61 | total: integer; // |
| 45 | * }; | 62 | * }; | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date:2026-02-08 | 2 | * @Date:2026-02-08 |
| 3 | * @Description: 我的消息页 - 使用 LoadMoreList 组件重构版本 | 3 | * @Description: 我的消息页 - 使用 LoadMoreList 组件重构版本 |
| 4 | + * @Update:2026-02-13 API 新增 title 字段,直接使用 API 返回的标题 | ||
| 4 | --> | 5 | --> |
| 5 | <template> | 6 | <template> |
| 6 | <LoadMoreList | 7 | <LoadMoreList |
| ... | @@ -30,7 +31,9 @@ | ... | @@ -30,7 +31,9 @@ |
| 30 | <!-- 顶部:标题与红点 --> | 31 | <!-- 顶部:标题与红点 --> |
| 31 | <view class="flex justify-between items-start mb-2"> | 32 | <view class="flex justify-between items-start mb-2"> |
| 32 | <view class="flex-1 mr-2 relative"> | 33 | <view class="flex-1 mr-2 relative"> |
| 34 | + <!-- 未读红点 --> | ||
| 33 | <view v-if="item.status === 'send'" class="absolute -left-2 top-1.5 w-1.5 h-1.5 bg-red-500 rounded-full"></view> | 35 | <view v-if="item.status === 'send'" class="absolute -left-2 top-1.5 w-1.5 h-1.5 bg-red-500 rounded-full"></view> |
| 36 | + <!-- 标题:优先使用 API 返回的 title,降级使用 note 第一行 --> | ||
| 34 | <text class="text-lg font-bold text-gray-900 line-clamp-1 leading-snug"> | 37 | <text class="text-lg font-bold text-gray-900 line-clamp-1 leading-snug"> |
| 35 | {{ item.title || getItemTitle(item.note) }} | 38 | {{ item.title || getItemTitle(item.note) }} |
| 36 | </text> | 39 | </text> |
| ... | @@ -48,7 +51,7 @@ | ... | @@ -48,7 +51,7 @@ |
| 48 | <!-- 中间:内容预览 --> | 51 | <!-- 中间:内容预览 --> |
| 49 | <view class="mb-4"> | 52 | <view class="mb-4"> |
| 50 | <text class="text-sm text-gray-500 line-clamp-2 leading-relaxed"> | 53 | <text class="text-sm text-gray-500 line-clamp-2 leading-relaxed"> |
| 51 | - {{ getItemPreview(item.note) || '点击查看详情' }} | 54 | + {{ getItemPreview(item.note) }} |
| 52 | </text> | 55 | </text> |
| 53 | </view> | 56 | </view> |
| 54 | 57 | ||
| ... | @@ -98,10 +101,17 @@ const loadingMore = ref(false) | ... | @@ -98,10 +101,17 @@ const loadingMore = ref(false) |
| 98 | const isFirstLoad = ref(true) | 101 | const isFirstLoad = ref(true) |
| 99 | 102 | ||
| 100 | /** | 103 | /** |
| 101 | - * 提取消息标题(第一行或截取) | 104 | + * 提取消息标题(降级方案:从 note 第一行提取) |
| 102 | * | 105 | * |
| 106 | + * @description 当 API 未返回 title 时,从 note 内容的第一行提取标题 | ||
| 103 | * @param {string} note - 消息内容 | 107 | * @param {string} note - 消息内容 |
| 104 | * @returns {string} 标题 | 108 | * @returns {string} 标题 |
| 109 | + * | ||
| 110 | + * @example | ||
| 111 | + * // API 已返回 title | ||
| 112 | + * getItemTitle(note) // 不使用,直接显示 item.title | ||
| 113 | + * // API 未返回 title(降级) | ||
| 114 | + * getItemTitle('这是第一行标题\n这是内容') // 返回: '这是第一行标题' | ||
| 105 | */ | 115 | */ |
| 106 | const getItemTitle = (note) => { | 116 | const getItemTitle = (note) => { |
| 107 | if (!note) return '暂无消息内容' | 117 | if (!note) return '暂无消息内容' |
| ... | @@ -112,28 +122,33 @@ const getItemTitle = (note) => { | ... | @@ -112,28 +122,33 @@ const getItemTitle = (note) => { |
| 112 | // 移除富文本标签(简单处理) | 122 | // 移除富文本标签(简单处理) |
| 113 | const textOnly = firstLine.replace(/<[^>]+>/g, '').trim() | 123 | const textOnly = firstLine.replace(/<[^>]+>/g, '').trim() |
| 114 | 124 | ||
| 115 | - // 如果第一行太长,截取前50个字符 | 125 | + // 如果第一行太长,截取前 50 个字符 |
| 116 | return textOnly.length > 50 ? textOnly.substring(0, 50) + '...' : textOnly | 126 | return textOnly.length > 50 ? textOnly.substring(0, 50) + '...' : textOnly |
| 117 | } | 127 | } |
| 118 | 128 | ||
| 119 | /** | 129 | /** |
| 120 | - * 提取消息预览(移除第一行后的内容) | 130 | + * 提取消息预览 |
| 121 | * | 131 | * |
| 132 | + * @description 移除第一行标题后的内容作为预览 | ||
| 122 | * @param {string} note - 消息内容 | 133 | * @param {string} note - 消息内容 |
| 123 | * @returns {string} 预览内容 | 134 | * @returns {string} 预览内容 |
| 135 | + * | ||
| 136 | + * @example | ||
| 137 | + * getItemPreview('标题\n内容第二行\n内容第三行') // 返回: '内容第二行\n内容第三行' | ||
| 138 | + * getItemPreview('只有单行内容') // 返回: '点击查看详情' | ||
| 124 | */ | 139 | */ |
| 125 | const getItemPreview = (note) => { | 140 | const getItemPreview = (note) => { |
| 126 | - if (!note) return '' | 141 | + if (!note) return '点击查看详情' |
| 127 | 142 | ||
| 128 | - // 移除第一行(已在标题显示) | 143 | + // 移除第一行(已作为标题显示) |
| 129 | const lines = note.split('\n') | 144 | const lines = note.split('\n') |
| 130 | if (lines.length > 1) { | 145 | if (lines.length > 1) { |
| 131 | // 移除富文本标签(简单处理) | 146 | // 移除富文本标签(简单处理) |
| 132 | const preview = lines.slice(1).join('\n').replace(/<[^>]+>/g, '').trim() | 147 | const preview = lines.slice(1).join('\n').replace(/<[^>]+>/g, '').trim() |
| 133 | - return preview.substring(0, 100) // 限制预览长度 | 148 | + return preview || '点击查看详情' |
| 134 | } | 149 | } |
| 135 | 150 | ||
| 136 | - return '' // 只有一行时不显示预览 | 151 | + return '点击查看详情' // 只有一行时 |
| 137 | } | 152 | } |
| 138 | 153 | ||
| 139 | /** | 154 | /** |
| ... | @@ -167,11 +182,8 @@ const fetchMessageList = async (params = {}, isLoadMore = false) => { | ... | @@ -167,11 +182,8 @@ const fetchMessageList = async (params = {}, isLoadMore = false) => { |
| 167 | 182 | ||
| 168 | // 处理列表数据 | 183 | // 处理列表数据 |
| 169 | if (res.data.list?.length) { | 184 | if (res.data.list?.length) { |
| 170 | - // 模拟标题数据 | 185 | + // 直接使用 API 返回的数据(title 字段由后端提供) |
| 171 | - const listData = res.data.list.map(item => ({ | 186 | + const listData = res.data.list |
| 172 | - ...item, | ||
| 173 | - title: item.title || '关于系统维护升级的通知公告' // 模拟标题 | ||
| 174 | - })) | ||
| 175 | 187 | ||
| 176 | if (isLoadMore) { | 188 | if (isLoadMore) { |
| 177 | // 加载更多:追加数据 | 189 | // 加载更多:追加数据 | ... | ... |
-
Please register or login to post a comment