Commit 984b2e69cea685b431c7c3897944aed89dfd21b1
1 parent
c09c0eda
养护
Showing
1 changed file
with
152 additions
and
53 deletions
pages-sub/daily/maintain-manage/type-list.vue
| ... | ... | @@ -3,12 +3,20 @@ |
| 3 | 3 | <template v-if="cardList.length > 0"> |
| 4 | 4 | <view class="type-card" v-for="item in cardList" :key="item.key" hover-class="type-card--hover" |
| 5 | 5 | @click="toNextPage(item)"> |
| 6 | - <view class="info-row" v-for="row in item.rows" :key="row.label"> | |
| 7 | - <!-- ✅计划类型:不渲染左侧label文字;其他行正常显示label --> | |
| 8 | - <text class="info-label" v-if="row.label !== '计划类型'">{{ row.label }}:</text> | |
| 9 | - <view class="info-value"> | |
| 10 | - <view class="info-line" v-for="(value, idx) in row.values" :key="idx" | |
| 11 | - :class="{ 'info-line--count': row.label === '待完成数' }">{{ value }}</view> | |
| 6 | + | |
| 7 | + <!-- 左上图标:按计划类型显示不同颜色图标 --> | |
| 8 | + <view class="card-icon" :class="item.iconClass || 'icon-default'"> | |
| 9 | + <text class="icon-text">{{ item.iconChar || '📋' }}</text> | |
| 10 | + </view> | |
| 11 | + | |
| 12 | + <!-- 名称:第一行大字 --> | |
| 13 | + <view class="card-name">{{ item.nameText }}</view> | |
| 14 | + | |
| 15 | + <!-- 底部:灰色文字 + 右侧数字 --> | |
| 16 | + <view class="card-bottom"> | |
| 17 | + <text class="card-label">待完成任务</text> | |
| 18 | + <view class="card-badge"> | |
| 19 | + <text class="card-count">{{ item.countText }}</text> | |
| 12 | 20 | </view> |
| 13 | 21 | </view> |
| 14 | 22 | </view> |
| ... | ... | @@ -18,16 +26,22 @@ |
| 18 | 26 | </template> |
| 19 | 27 | </view> |
| 20 | 28 | </template> |
| 29 | + | |
| 21 | 30 | <script setup lang="ts"> |
| 22 | 31 | import { ref } from 'vue' |
| 23 | -import { onShow, onUnload } from '@dcloudio/uni-app'; | |
| 32 | +import { onShow, onUnload } from '@dcloudio/uni-app' | |
| 33 | + | |
| 24 | 34 | const cardList = ref<Array<{ |
| 25 | 35 | key: string |
| 26 | 36 | planTypeId: string | number |
| 27 | 37 | batchNos: string[] |
| 38 | + nameText: string | |
| 39 | + countText: string | |
| 40 | + iconClass?: string | |
| 41 | + iconChar?: string | |
| 28 | 42 | rows: Array<{ label: string; values: string[] }> |
| 29 | 43 | }>>([]) |
| 30 | -/** 日期字段可能是 'yyyy‑MM‑dd' 字符串(LocalDate)或时间戳,统一转成 yyyy‑MM‑dd */ | |
| 44 | + | |
| 31 | 45 | const formatDate = (value: any) => { |
| 32 | 46 | if (value === null || value === undefined || value === '') return '--' |
| 33 | 47 | if (Array.isArray(value)) { |
| ... | ... | @@ -39,18 +53,43 @@ const formatDate = (value: any) => { |
| 39 | 53 | } |
| 40 | 54 | return String(value).slice(0, 10) |
| 41 | 55 | } |
| 42 | -/** 去重并保持原顺序,合并卡片时避免同一个值重复占一行 */ | |
| 56 | + | |
| 43 | 57 | const uniq = (list: any[]) => Array.from(new Set(list.filter(v => v !== null && v !== undefined && v !== ''))) |
| 58 | + | |
| 59 | +/** 根据计划类型返回不同图标样式 */ | |
| 60 | +const getIconByType = (name: string) => { | |
| 61 | + const n = (name || '').toLowerCase() | |
| 62 | + if (n.includes('补植') || n.includes('种植')) { | |
| 63 | + return { iconClass: 'icon-blue', iconChar: '🌱' } | |
| 64 | + } | |
| 65 | + if (n.includes('修剪')) { | |
| 66 | + return { iconClass: 'icon-orange', iconChar: '✂️' } | |
| 67 | + } | |
| 68 | + if (n.includes('浇水') || n.includes('防寒') || n.includes('灌溉')) { | |
| 69 | + return { iconClass: 'icon-cyan', iconChar: '💧' } | |
| 70 | + } | |
| 71 | + if (n.includes('保洁') || n.includes('清洁')) { | |
| 72 | + return { iconClass: 'icon-green', iconChar: '🗑️' } | |
| 73 | + } | |
| 74 | + if (n.includes('病虫害') || n.includes('防治')) { | |
| 75 | + return { iconClass: 'icon-red', iconChar: '🛡️' } | |
| 76 | + } | |
| 77 | + if (n.includes('施肥') || n.includes('除草')) { | |
| 78 | + return { iconClass: 'icon-sky', iconChar: '🎯' } | |
| 79 | + } | |
| 80 | + return { iconClass: 'icon-default', iconChar: '📋' } | |
| 81 | +} | |
| 82 | + | |
| 44 | 83 | onShow(() => { |
| 45 | 84 | const item = uni.getStorageSync('temp_maintain_item') |
| 46 | 85 | if (!item) { |
| 47 | 86 | uni.showToast({ |
| 48 | 87 | title: '数据异常,请返回重试', |
| 49 | 88 | icon: 'none' |
| 50 | - }); | |
| 89 | + }) | |
| 51 | 90 | return |
| 52 | 91 | } |
| 53 | - const roadName = item.roadName || '--' | |
| 92 | + | |
| 54 | 93 | cardList.value = (item.planTypes || []).map((type: any) => { |
| 55 | 94 | const batches = Array.isArray(type.batches) && type.batches.length |
| 56 | 95 | ? type.batches |
| ... | ... | @@ -61,29 +100,39 @@ onShow(() => { |
| 61 | 100 | endTime: null, |
| 62 | 101 | todayPendingCount: type.todayPendingCount |
| 63 | 102 | })) |
| 103 | + | |
| 64 | 104 | const batchNos = batches.map((batch: any) => batch.batchNo).filter(Boolean) |
| 65 | 105 | const pendingCount = batches.reduce((sum: number, batch: any) => sum + Number(batch.todayPendingCount || 0), 0) |
| 106 | + const icon = getIconByType(type.planTypeName || '') | |
| 107 | + | |
| 66 | 108 | return { |
| 67 | 109 | key: String(type.planTypeId), |
| 68 | 110 | planTypeId: type.planTypeId, |
| 69 | 111 | batchNos, |
| 112 | + nameText: type.planTypeName || '--', | |
| 113 | + countText: `${pendingCount}`, | |
| 114 | + iconClass: icon.iconClass, | |
| 115 | + iconChar: icon.iconChar, | |
| 70 | 116 | rows: [ |
| 71 | 117 | { label: '计划类型', values: [type.planTypeName || '--'] }, |
| 72 | 118 | { label: '待完成数', values: [`${pendingCount}次`] } |
| 73 | 119 | ] |
| 74 | 120 | } |
| 75 | 121 | }) |
| 76 | -}); | |
| 122 | +}) | |
| 123 | + | |
| 77 | 124 | const toNextPage = (item: any) => { |
| 78 | 125 | uni.setStorageSync('temp_maintain_rawList', item.batchNos || []) |
| 79 | 126 | uni.navigateTo({ |
| 80 | 127 | url: `/pages-sub/daily/maintain-manage/type-list-page?planTypeId=${item.planTypeId}` |
| 81 | 128 | }) |
| 82 | 129 | } |
| 83 | -onUnload(()=>{ | |
| 130 | + | |
| 131 | +onUnload(() => { | |
| 84 | 132 | uni.removeStorageSync('temp_maintain_item') |
| 85 | 133 | }) |
| 86 | 134 | </script> |
| 135 | + | |
| 87 | 136 | <style scoped lang="scss"> |
| 88 | 137 | .type-grid { |
| 89 | 138 | display: flex; |
| ... | ... | @@ -91,63 +140,113 @@ onUnload(()=>{ |
| 91 | 140 | gap: 24rpx; |
| 92 | 141 | padding: 24rpx; |
| 93 | 142 | } |
| 94 | -/* 一行两张卡片,总宽度扣除中间间隙 */ | |
| 143 | + | |
| 95 | 144 | .type-card { |
| 96 | 145 | width: calc((100% - 24rpx) / 2); |
| 146 | + // min-height: 240rpx; | |
| 97 | 147 | box-sizing: border-box; |
| 98 | 148 | display: flex; |
| 99 | 149 | flex-direction: column; |
| 100 | - gap: 8rpx; | |
| 150 | + justify-content: space-between; | |
| 101 | 151 | background: #ffffff; |
| 102 | - border-radius: 16rpx; | |
| 103 | - padding: 24rpx; | |
| 104 | - box-shadow: 0 4rpx 16rpx rgba(17, 24, 39, 0.06); | |
| 105 | - transition: background-color 0.15s ease; | |
| 152 | + border-radius: 24rpx; | |
| 153 | + padding: 20rpx 20rpx; | |
| 154 | + box-shadow: 0 4rpx 20rpx rgba(17, 24, 39, 0.08); | |
| 155 | + transition: transform 0.15s ease, background-color 0.15s ease; | |
| 156 | + | |
| 106 | 157 | &--hover { |
| 107 | - background: #F4F5F7; | |
| 158 | + background: #F7F8FA; | |
| 108 | 159 | } |
| 109 | 160 | } |
| 110 | -.info-row { | |
| 161 | + | |
| 162 | +/* 左上图标 */ | |
| 163 | +.card-icon { | |
| 164 | + width: 62rpx; | |
| 165 | + height: 62rpx; | |
| 166 | + border-radius: 16rpx; | |
| 111 | 167 | display: flex; |
| 112 | - align-items: flex-start; | |
| 168 | + align-items: center; | |
| 169 | + justify-content: center; | |
| 170 | + background: #F3F4F6; | |
| 113 | 171 | } |
| 114 | -.info-label { | |
| 115 | - width: 130rpx !important; | |
| 116 | - flex-shrink: 0; /* 标签禁止压缩 */ | |
| 117 | - font-size: 26rpx; | |
| 118 | - color: #6B7280; | |
| 119 | - line-height: 1.5; | |
| 172 | + | |
| 173 | +.icon-text { | |
| 174 | + font-size: 32rpx; | |
| 120 | 175 | } |
| 121 | -.info-value { | |
| 122 | - flex: 1; | |
| 123 | - min-width: 0; | |
| 124 | - /* ✅计划类型没有label时,去掉左边padding,顶格显示 */ | |
| 125 | - padding-left: 16rpx; | |
| 176 | + | |
| 177 | +.icon-blue { | |
| 178 | + background: #EAF4FF; | |
| 126 | 179 | } |
| 127 | -/* 当该行没有label的时候,value不要左边边距 */ | |
| 128 | -.info-row:not(:has(.info-label)) .info-value { | |
| 129 | - padding-left: 0; | |
| 180 | + | |
| 181 | +.icon-orange { | |
| 182 | + background: #FFF3E0; | |
| 130 | 183 | } |
| 131 | -.info-line { | |
| 132 | - font-size: 26rpx; | |
| 184 | + | |
| 185 | +.icon-cyan { | |
| 186 | + background: #E0F7FA; | |
| 187 | +} | |
| 188 | + | |
| 189 | +.icon-green { | |
| 190 | + background: #E8F5E9; | |
| 191 | +} | |
| 192 | + | |
| 193 | +.icon-red { | |
| 194 | + background: #FCE4EC; | |
| 195 | +} | |
| 196 | + | |
| 197 | +.icon-sky { | |
| 198 | + background: #E3F2FD; | |
| 199 | +} | |
| 200 | + | |
| 201 | +.icon-default { | |
| 202 | + background: #ECEFF1; | |
| 203 | +} | |
| 204 | + | |
| 205 | +/* 名称 */ | |
| 206 | +.card-name { | |
| 207 | + margin-top: 10rpx; | |
| 208 | + font-size: 32rpx; | |
| 209 | + font-weight: 600; | |
| 133 | 210 | color: #1F2937; |
| 134 | - line-height: 1.5; | |
| 135 | - /* 普通计划类型文字:超长省略 */ | |
| 136 | - &:not(.info-line--count) { | |
| 137 | - overflow: hidden; | |
| 138 | - text-overflow: ellipsis; | |
| 139 | - white-space: nowrap; | |
| 140 | - } | |
| 141 | - /* ✅待完成数:禁止省略、禁止截断,数字必须完整显示 */ | |
| 142 | - &--count { | |
| 143 | - color: #2563EB; | |
| 144 | - font-weight: 500; | |
| 145 | - white-space: normal !important; | |
| 146 | - overflow: visible !important; | |
| 147 | - text-overflow: clip !important; | |
| 148 | - } | |
| 211 | + line-height: 1.4; | |
| 212 | + overflow: hidden; | |
| 213 | + text-overflow: ellipsis; | |
| 214 | + white-space: nowrap; | |
| 215 | +} | |
| 216 | + | |
| 217 | +/* 底部:灰色文字 + 数字 */ | |
| 218 | +.card-bottom { | |
| 219 | + // margin-top:10px; | |
| 220 | + // padding-top: 20rpx; | |
| 221 | + display: flex; | |
| 222 | + align-items: center; | |
| 223 | + justify-content: space-between; | |
| 224 | +} | |
| 225 | + | |
| 226 | +.card-label { | |
| 227 | + font-size: 24rpx; | |
| 228 | + color: #9CA3AF; | |
| 229 | +} | |
| 230 | + | |
| 231 | +.card-badge { | |
| 232 | + min-width: 48rpx; | |
| 233 | + height: 48rpx; | |
| 234 | + padding: 0 14rpx; | |
| 235 | + border-radius: 24rpx; | |
| 236 | + background: #F3F4F6; | |
| 237 | + display: flex; | |
| 238 | + align-items: center; | |
| 239 | + justify-content: center; | |
| 240 | +} | |
| 241 | + | |
| 242 | +.card-count { | |
| 243 | + font-size: 26rpx; | |
| 244 | + font-weight: 600; | |
| 245 | + color: #2563EB; | |
| 149 | 246 | } |
| 247 | + | |
| 150 | 248 | .type-empty { |
| 249 | + width: 100%; | |
| 151 | 250 | padding: 120rpx 0; |
| 152 | 251 | text-align: center; |
| 153 | 252 | font-size: 26rpx; | ... | ... |