@liujitcn/kratos-uni-app-system 0.0.78 → 0.0.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,17 @@
2
2
  import { onShow } from '@dcloudio/uni-app'
3
3
  import { ref } from 'vue'
4
4
  import { navigateAppView, t } from '@liujitcn/kratos-uni-app-core'
5
+ import { useThemeStore } from '@liujitcn/kratos-uni-app-core/stores'
6
+ import { getMpCapsuleRightGap } from '@liujitcn/kratos-uni-app-core/utils/index'
5
7
  import { defNotificationService } from '../../../api/base/v1/notification'
6
8
  import type { Notification, NotificationCategory } from '../../../rpc/base/v1/notification'
7
9
  import { NotificationView } from '../../../rpc/base/v1/notification'
8
10
  import { notificationUnreadTotal, refreshNotificationSummary } from '../../../notification'
9
11
  import { resolveMessageCategoryIcon } from './icons'
10
12
 
13
+ const themeStore = useThemeStore()
14
+ /** MP-WEIXIN 原生胶囊按钮右侧避让宽度,写入 --mp-capsule-gap 供 .k-top 预留空间。 */
15
+ const capsuleGap = getMpCapsuleRightGap()
11
16
  const items = ref<Notification[]>([])
12
17
  const loading = ref(false)
13
18
  const cursorId = ref(0)
@@ -113,93 +118,105 @@ async function openDetail(item: Notification) {
113
118
  </script>
114
119
 
115
120
  <template>
116
- <view class="message-page">
117
- <view class="message-header">
121
+ <view class="message-page" :class="themeStore.themeClass">
122
+ <view class="k-top message-header" :style="{ '--mp-capsule-gap': `${capsuleGap}px` }">
118
123
  <view class="message-header__title">
119
- <text class="message-title">{{ t('system.notification.title') }}</text>
124
+ <text class="k-top__t2">{{ t('system.notification.title') }}</text>
120
125
  <view v-if="notificationUnreadTotal > 0" class="message-unread-dot" aria-hidden="true" />
121
126
  </view>
122
- <button
127
+ <view
123
128
  v-if="
124
129
  selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED &&
125
130
  notificationUnreadTotal > 0
126
131
  "
127
- class="message-action message-action--read message-header__action"
132
+ class="k-ch k-ch--pri"
128
133
  @tap="markAllRead"
129
134
  >
130
135
  {{ t('system.notification.mark_all_read') }}
131
- </button>
132
- </view>
133
- <view class="message-controls">
134
- <scroll-view class="message-category-scroll" scroll-x :show-scrollbar="false">
135
- <view class="message-category-list">
136
- <button
137
- class="message-category"
138
- :class="{ active: categoryId === undefined }"
139
- @tap="changeCategory()"
140
- >
141
- {{ t('system.notification.view.inbox') }}
142
- </button>
143
- <button
144
- v-for="category in categoryOptions"
145
- :key="category.id"
146
- class="message-category"
147
- :class="{ active: categoryId === category.id }"
148
- @tap="changeCategory(category.id)"
149
- >
150
- <uni-icons
151
- class="message-category__icon"
152
- :type="resolveMessageCategoryIcon(category.icon)"
153
- size="16"
154
- :color="categoryId === category.id ? '#fff' : category.color || '#64748b'"
155
- aria-hidden="true"
156
- />
157
- {{ category.name }}
158
- </button>
159
- </view>
160
- </scroll-view>
161
- <view class="message-tabs">
162
- <button
163
- v-for="option in viewOptions"
164
- :key="option.value"
165
- :class="['message-tab', { active: selectedView === option.value }]"
166
- @tap="changeView(option.value)"
167
- >
168
- {{ t(option.key) }}
169
- </button>
170
136
  </view>
171
137
  </view>
172
- <view v-for="item in items" :key="item.id" class="message-item" @tap="openDetail(item)">
173
- <view class="message-item__main">
174
- <text :class="['message-item__title', { unread: !item.read_at }]">{{ item.title }}</text>
175
- <text class="message-item__time">{{ item.received_at }}</text>
138
+ <view class="k-chips">
139
+ <view class="k-ch" :class="{ 'k-ch--pri': categoryId === undefined }" @tap="changeCategory()">
140
+ {{ t('system.notification.view.inbox') }}
176
141
  </view>
177
- <view class="message-item__category">
142
+ <view
143
+ v-for="category in categoryOptions"
144
+ :key="category.id"
145
+ class="k-ch"
146
+ :class="{ 'k-ch--pri': categoryId === category.id }"
147
+ @tap="changeCategory(category.id)"
148
+ >
178
149
  <uni-icons
179
- class="message-item__category-icon"
180
- :type="resolveMessageCategoryIcon(item.category_icon)"
150
+ :type="resolveMessageCategoryIcon(category.icon)"
181
151
  size="16"
182
- :color="item.category_color || '#64748b'"
152
+ :color="category.color || '#64748b'"
183
153
  aria-hidden="true"
184
154
  />
185
- <text>{{ item.category_name }}</text>
155
+ {{ category.name }}
186
156
  </view>
187
- <view class="message-item__actions">
188
- <button
189
- v-if="selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED && item.allow_archive"
190
- @tap.stop="toggleArchive(item)"
191
- >
192
- {{ t('system.notification.action.archive') }}
193
- </button>
194
- <button
195
- v-if="selectedView === NotificationView.NOTIFICATION_VIEW_ARCHIVED"
196
- @tap.stop="toggleArchive(item)"
157
+ </view>
158
+ <view class="k-pills message-tabs">
159
+ <view
160
+ v-for="option in viewOptions"
161
+ :key="option.value"
162
+ class="k-pills__item message-tab"
163
+ :class="{ 'k-pills__item--on': selectedView === option.value }"
164
+ @tap="changeView(option.value)"
165
+ >
166
+ {{ t(option.key) }}
167
+ </view>
168
+ </view>
169
+ <view class="k-msg-list">
170
+ <view
171
+ v-for="item in items"
172
+ :key="item.id"
173
+ class="k-msg-item"
174
+ :class="{ 'k-msg-item--unread': !item.read_at }"
175
+ @tap="openDetail(item)"
176
+ >
177
+ <view class="k-msg-item__head">
178
+ <view class="k-msg-item__icon">
179
+ <uni-icons
180
+ :type="resolveMessageCategoryIcon(item.category_icon)"
181
+ size="18"
182
+ :color="item.category_color || '#64748b'"
183
+ aria-hidden="true"
184
+ />
185
+ </view>
186
+ <view class="message-item__body">
187
+ <text class="k-msg-item__title">{{ item.title }}</text>
188
+ <text class="k-msg-item__meta">{{ item.category_name }}</text>
189
+ </view>
190
+ <text class="k-msg-item__time">{{ item.received_at }}</text>
191
+ </view>
192
+ <view
193
+ v-if="
194
+ selectedView === NotificationView.NOTIFICATION_VIEW_ARCHIVED ||
195
+ item.allow_archive ||
196
+ item.allow_delete
197
+ "
198
+ class="k-msg-item__actions"
197
199
  >
198
- {{ t('system.notification.action.restore') }}
199
- </button>
200
- <button v-if="item.allow_delete" @tap.stop="deleteItem(item)">
201
- {{ t('system.notification.action.delete') }}
202
- </button>
200
+ <text
201
+ v-if="
202
+ selectedView !== NotificationView.NOTIFICATION_VIEW_ARCHIVED && item.allow_archive
203
+ "
204
+ class="k-msg-item__action"
205
+ @tap.stop="toggleArchive(item)"
206
+ >
207
+ {{ t('system.notification.action.archive') }}
208
+ </text>
209
+ <text
210
+ v-if="selectedView === NotificationView.NOTIFICATION_VIEW_ARCHIVED"
211
+ class="k-msg-item__action"
212
+ @tap.stop="toggleArchive(item)"
213
+ >
214
+ {{ t('system.notification.action.restore') }}
215
+ </text>
216
+ <text v-if="item.allow_delete" class="k-msg-item__action" @tap.stop="deleteItem(item)">
217
+ {{ t('system.notification.action.delete') }}
218
+ </text>
219
+ </view>
203
220
  </view>
204
221
  </view>
205
222
  <button v-if="!finished" class="load-more" :loading="loading" @tap="loadMore">
@@ -212,18 +229,20 @@ async function openDetail(item: Notification) {
212
229
  </template>
213
230
 
214
231
  <style scoped lang="scss">
232
+ /* 仅页面局部布局;视觉词汇统一来自 core 的 .k-* 全局类。 */
215
233
  .message-page {
216
234
  box-sizing: border-box;
217
235
  min-height: 100vh;
218
- padding: 16rpx 24rpx calc(120rpx + env(safe-area-inset-bottom));
219
- background: var(--kratos-color-background, #f7f8fa);
220
- color: var(--kratos-color-text, #1f2937);
236
+ padding: calc(16rpx + env(safe-area-inset-top)) 24rpx calc(200rpx + env(safe-area-inset-bottom));
237
+ background: var(--kratos-bg-gradient);
238
+ color: var(--kratos-color-text);
221
239
  }
240
+ /* #ifdef MP-WEIXIN */
241
+ .message-page {
242
+ padding-top: calc(44px + 16rpx);
243
+ }
244
+ /* #endif */
222
245
  .message-header {
223
- display: flex;
224
- align-items: center;
225
- justify-content: space-between;
226
- gap: 20rpx;
227
246
  padding: 20rpx 4rpx 24rpx;
228
247
  }
229
248
  .message-header__title {
@@ -231,181 +250,45 @@ async function openDetail(item: Notification) {
231
250
  align-items: center;
232
251
  min-width: 0;
233
252
  }
234
- .message-title {
235
- display: block;
236
- font-size: 40rpx;
237
- font-weight: 700;
238
- line-height: 1.35;
239
- color: var(--kratos-color-text, #1f2937);
240
- }
241
253
  .message-unread-dot {
242
254
  width: 12rpx;
243
255
  height: 12rpx;
244
- margin-left: 8rpx;
256
+ margin-left: 12rpx;
245
257
  border-radius: 50%;
246
- background: #e5484d;
247
- }
248
- .message-controls {
249
- margin-bottom: 24rpx;
250
- }
251
- .message-category-scroll {
252
- width: 100%;
253
- white-space: nowrap;
254
- }
255
- .message-category-list {
256
- display: flex;
257
- gap: 12rpx;
258
- width: max-content;
259
- padding-bottom: 4rpx;
260
- }
261
- .message-category,
262
- .message-tabs,
263
- .message-item__actions {
264
- display: flex;
265
- align-items: center;
266
- }
267
- .message-category {
268
- flex-shrink: 0;
269
- height: 64rpx;
270
- margin: 0;
271
- padding: 0 22rpx;
272
- border: 1rpx solid var(--kratos-color-border, #e2e8f0);
273
- border-radius: 32rpx;
274
- background: #fff;
275
- color: var(--kratos-color-text-muted, #6b7280);
276
- font-size: 24rpx;
277
- line-height: 64rpx;
278
- white-space: nowrap;
279
- }
280
- .message-category.active {
281
- border-color: var(--kratos-color-primary, #27ba9b);
282
- background: var(--kratos-color-primary, #27ba9b);
283
- color: #fff;
258
+ background: var(--kratos-color-danger);
259
+ box-shadow: 0 0 16rpx var(--kratos-color-danger);
284
260
  }
285
261
  .message-tabs {
286
- gap: 12rpx;
287
- margin-top: 18rpx;
288
- padding: 6rpx;
289
- border-radius: 12rpx;
290
- background: #eef1f3;
291
- }
292
- .message-item__actions {
293
- gap: 12rpx;
294
- flex-wrap: wrap;
295
- justify-content: flex-end;
262
+ display: flex;
263
+ margin-top: 4rpx;
296
264
  }
297
265
  .message-tab {
298
- box-sizing: border-box;
299
266
  flex: 1;
300
- min-width: 0;
301
- height: 68rpx;
302
- margin: 0;
303
- padding: 0 12rpx;
304
- border: 0;
305
- border-radius: 8rpx;
306
- background: transparent;
307
- color: var(--kratos-color-text-muted, #6b7280);
308
- font-size: 26rpx;
309
- line-height: 68rpx;
310
- white-space: nowrap;
311
- }
312
- .message-tab::after,
313
- .message-category::after,
314
- .message-action::after,
315
- .message-item__actions button::after,
316
- .load-more::after {
317
- border: 0;
318
- }
319
- .message-tab.active {
320
- background: var(--kratos-color-primary, #27ba9b);
321
- color: #fff;
322
- }
323
- .message-action,
324
- .message-item__actions button {
325
- box-sizing: border-box;
326
- flex-shrink: 0;
327
- width: auto;
328
- height: 68rpx;
329
- margin: 0;
330
- padding: 0 20rpx;
331
- border: 0;
332
- border-radius: 8rpx;
333
- background: #eef1f3;
334
- color: var(--kratos-color-text, #1f2937);
335
- font-size: 24rpx;
336
- line-height: 68rpx;
337
- white-space: nowrap;
338
- }
339
- .message-action--read {
340
- background: #e8f8f4;
341
- color: var(--kratos-color-primary, #16806d);
342
267
  }
343
- .message-header__action {
344
- height: 56rpx;
345
- padding: 0 18rpx;
346
- line-height: 56rpx;
347
- }
348
- .message-item__actions button {
349
- height: 56rpx;
350
- padding: 0 16rpx;
351
- font-size: 22rpx;
352
- line-height: 56rpx;
353
- }
354
- .message-item {
355
- margin-bottom: 16rpx;
356
- padding: 28rpx;
357
- border-radius: 12rpx;
358
- background: #fff;
359
- box-shadow: 0 4rpx 16rpx rgba(31, 41, 55, 0.05);
360
- }
361
- .message-item__main {
362
- display: flex;
363
- align-items: center;
364
- justify-content: space-between;
365
- gap: 20rpx;
366
- }
367
- .message-item__title {
368
- display: block;
369
- min-width: 0;
268
+ .message-item__body {
370
269
  flex: 1;
371
- overflow: hidden;
372
- color: var(--kratos-color-text, #1f2937);
373
- text-overflow: ellipsis;
374
- white-space: nowrap;
375
- }
376
- .message-item__title.unread {
377
- color: var(--kratos-color-text, #1f2937);
378
- font-weight: 700;
379
- }
380
- .message-item__time,
381
- .message-item__category {
382
- color: var(--kratos-color-text-muted, #6b7280);
383
- font-size: 24rpx;
384
- }
385
- .message-item__time {
386
- flex-shrink: 0;
387
- }
388
- .message-item__category {
389
- display: flex;
390
- align-items: center;
391
- margin-top: 14rpx;
270
+ min-width: 0;
392
271
  }
393
272
  .load-more {
394
273
  box-sizing: border-box;
395
274
  width: 100%;
396
- height: 72rpx;
275
+ height: 76rpx;
397
276
  margin-top: 24rpx;
398
277
  padding: 0 24rpx;
278
+ border: 1rpx solid var(--kratos-color-border);
279
+ border-radius: 16rpx;
280
+ background: var(--kratos-color-surface-2);
281
+ color: var(--kratos-color-text);
282
+ font-size: 26rpx;
283
+ line-height: 74rpx;
284
+ }
285
+ .load-more::after {
399
286
  border: 0;
400
- border-radius: 8rpx;
401
- background: #eef1f3;
402
- color: var(--kratos-color-text, #1f2937);
403
- font-size: 28rpx;
404
- line-height: 72rpx;
405
287
  }
406
288
  .empty {
407
289
  padding: 120rpx 0;
408
- color: var(--kratos-color-text-muted, #6b7280);
290
+ color: var(--kratos-color-text-dim);
291
+ font-family: var(--kratos-font-mono);
409
292
  text-align: center;
410
293
  }
411
294
  </style>