| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- <template>
- <view class="ui-list-card" @click="$emit('click')">
- <view class="card-header">
- <view class="title-wrap">
- <text class="title">{{ title || '未命名标题' }}</text>
- </view>
- <view
- class="status-tag"
- v-if="statusLabel"
- :class="['status-' + (statusType || 'default')]"
- >
- {{ statusLabel }}
- </view>
- </view>
-
- <view class="card-body">
- <slot></slot>
- </view>
-
- <view class="card-footer" v-if="$slots.footer">
- <slot name="footer"></slot>
- </view>
-
- <!-- 装饰性元素 -->
- <view class="card-accent" :class="['accent-' + (statusType || 'primary')]"></view>
- </view>
- </template>
- <script setup lang="ts">
- /**
- * UI 通用组件 - 列表卡片
- * 封装统一的阴影、圆角、标签定位以及左侧装饰条。
- * 适用于:项列表、待办项、审批单等。
- */
- defineProps<{
- /** 标题文字 */
- title: string;
- /** 状态文字(如:待审批、已完成) */
- statusLabel?: string;
- /** 状态对应的颜色类型 (success/error/warning/primary/info/default) */
- statusType?: string;
- }>();
- defineEmits(['click']);
- </script>
- <style lang="scss" scoped>
- .ui-list-card {
- background-color: #ffffff;
- border-radius: 20rpx;
- padding: 30rpx 36rpx;
- margin-bottom: 24rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.03);
- position: relative;
- overflow: hidden;
- transition: all 0.2s;
- &:active {
- transform: scale(0.985);
- background-color: #f8fafc;
- box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.02);
- }
- /* 左侧装饰条 */
- .card-accent {
- position: absolute;
- left: 0;
- top: 50%;
- transform: translateY(-50%);
- width: 8rpx;
- height: 100%;
- background-color: #1c9bfd;
- border-radius: 0 4rpx 4rpx 0;
- &.accent-success { background-color: #52c41a; }
- &.accent-error { background-color: #ff4d4f; }
- &.accent-warning { background-color: #faad14; }
- &.accent-info { background-color: #94a3b8; }
- &.accent-default { background-color: #e2e8f0; }
- }
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 24rpx;
- padding-bottom: 20rpx;
- border-bottom: 2rpx dashed #f1f5f9;
- .title-wrap {
- flex: 1;
- margin-right: 20rpx;
- .title {
- font-size: 32rpx;
- font-weight: 600;
- color: #343a3f;
- line-height: 1.45;
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- line-clamp: 2;
- overflow: hidden;
- }
- }
- .status-tag {
- font-size: 24rpx;
- padding: 6rpx 18rpx;
- border-radius: 8rpx;
- white-space: nowrap;
- font-weight: 500;
- flex-shrink: 0;
- &.status-primary { color: #1c9bfd; background-color: rgba(28, 155, 253, 0.1); }
- &.status-success { color: #52c41a; background-color: rgba(82, 196, 26, 0.1); }
- &.status-error { color: #ff4d4f; background-color: rgba(255, 77, 79, 0.1); }
- &.status-warning { color: #faad14; background-color: rgba(250, 173, 20, 0.1); }
- &.status-info { color: #94a3b8; background-color: #f1f5f9; }
- &.status-default { color: #64748b; background-color: #f8fafc; border: 1rpx solid #e2e8f0; }
- }
- }
- .card-body {
- width: 100%;
- /* 配合 CommonInfoRow 使用效果最佳 */
- }
- .card-footer {
- margin-top: 24rpx;
- padding-top: 20rpx;
- border-top: 2rpx solid #f8fafc;
- display: flex;
- justify-content: flex-end;
- }
- }
- </style>
|