NotificationItem.vue 3.24 KB
<template>
  <view class="notification-item" @click="onClick">
    <view class="icon-container" :class="[`bg-${type}`]">
      <uv-icon :name="iconName" color="#FFFFFF" size="24"></uv-icon>
    </view>
    <view class="content">
      <view class="title">{{ title }}</view>
      <view class="message">{{ message }}</view>
    </view>
    <view class="time">{{ time }}</view>
    <view v-if="unread" class="badge">{{ unreadCount }}</view>
  </view>
</template>

<script setup>
import { computed } from 'vue';

// 定义props
const props = defineProps({
  type: {
    type: String,
    default: 'info',
    validator: (value) => ['system', 'task', 'alert', 'work', 'alarm'].includes(value)
  },
  title: {
    type: String,
    required: true
  },
  message: {
    type: String,
    required: true
  },
  time: {
    type: String,
    required: true
  },
  unread: {
    type: Boolean,
    default: false
  },
  unreadCount: {
    type: [String, Number],
    default: '0'
  }
});

const emit = defineEmits(['click']);

const iconName = computed(() => {
  const iconMap = {
    system: 'bell',
    task: 'checkmark-circle',
    alert: 'error-circle',
    work: 'file-text',
    alarm: 'warning'
  };
  return iconMap[props.type] || 'bell';
});

// 方法
const onClick = () => {
  emit('click');
};
</script>

<style lang="scss" scoped>
.notification-item {
  display: flex;
  align-items: center;
  padding: 32rpx;
  background-color: #FFFFFF;
  border-bottom: 2rpx solid #F0F0F0;
  position: relative;
  
  .icon-container {
    width: 40rpx;
    height: 40rpx;
    border-radius: 16rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 12rpx;
  }
  
  .bg-system {
    background-color: #4080FF;
  }
  
  .bg-task {
    background-color: #00C389;
  }
  
  .bg-alert {
    background-color: #FF4D4F;
  }
  
  .bg-work {
    background-color: #FFA940;
  }
  
  .bg-alarm {
    background-color: #722ED1;
  }
  
  .content {
    flex: 1;
    overflow: hidden;
    
    .title {
      font-size: 32rpx;
      font-weight: 500;
      color: #333333;
      margin-bottom: 8rpx;
    }
    
    .message {
      font-size: 28rpx;
      color: #999999;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
  }
  
  .time {
    font-size: 24rpx;
    color: #999999;
    margin-left: 16rpx;
  }
  
  .badge {
    position: absolute;
    top: 32rpx;
    right: 32rpx;
    min-width: 36rpx;
    height: 36rpx;
    border-radius: 18rpx;
    background-color: #FF4D4F;
    color: #FFFFFF;
    font-size: 24rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
  }
}

/* 适配iOS和Android的差异 */
/* iOS通常需要更圆润的视觉效果 */
/* Android通常需要更扁平的视觉效果 */
/* 使用条件编译实现平台特定样式 */
/* #ifdef APP-PLUS */
.notification-item {
  /* App平台通用样式 */
}
/* #endif */

/* #ifdef APP-PLUS-NVUE */
.notification-item {
  /* App nvue平台特定样式 */
}
/* #endif */

/* #ifdef APP-PLUS-IOS */
.notification-item {
  .icon-container {
    border-radius: 20rpx; /* iOS更圆润 */
  }
}
/* #endif */

/* #ifdef APP-PLUS-ANDROID */
.notification-item {
  .icon-container {
    border-radius: 12rpx; /* Android更方正 */
  }
}
/* #endif */
</style>