Commit 984b2e69cea685b431c7c3897944aed89dfd21b1

Authored by 刘淇
1 parent c09c0eda

养护

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) =&gt; {
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(() =&gt; {
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(()=&gt;{
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;
... ...