Showing
1 changed file
with
113 additions
and
9 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 12:53:15 | 2 | * @Date: 2024-07-23 12:53:15 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-24 11:05:03 | 4 | + * @LastEditTime: 2024-07-24 14:44:31 |
| 5 | * @FilePath: /temple_material_request/src/views/material_request.vue | 5 | * @FilePath: /temple_material_request/src/views/material_request.vue |
| 6 | * @Description: 申领物资页面 | 6 | * @Description: 申领物资页面 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <div class="material-request-page"> | 9 | <div class="material-request-page"> |
| 10 | + | ||
| 10 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> | 11 | <van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor"> |
| 11 | <van-tab v-for="index in 8" :title="'标签 ' + index"> | 12 | <van-tab v-for="index in 8" :title="'标签 ' + index"> |
| 12 | <div class="list-wrapper"> | 13 | <div class="list-wrapper"> |
| 13 | <van-sticky :offset-top="44"> | 14 | <van-sticky :offset-top="44"> |
| 14 | <van-row justify="space-between" class="select-all-item"> | 15 | <van-row justify="space-between" class="select-all-item"> |
| 15 | - <van-col span="8"><van-icon name="passed" size="1.25rem" /> <span :style="{ color: styleColor.baseColor }">全选</span></van-col> | 16 | + <van-col span="8"> |
| 17 | + <van-icon v-if="is_all_checked" @click="onCheckAll()" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 18 | + <van-icon v-else name="passed" @click="onCheckAll()" size="1.25rem" /> | ||
| 19 | + <span @click="onCheckAll()" :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 20 | + </van-col> | ||
| 16 | <van-col span="16" style="text-align: right; font-size: 0.85rem; color: #666666;">参考上次同类活动的领用情况</van-col> | 21 | <van-col span="16" style="text-align: right; font-size: 0.85rem; color: #666666;">参考上次同类活动的领用情况</van-col> |
| 17 | </van-row> | 22 | </van-row> |
| 18 | </van-sticky> | 23 | </van-sticky> |
| ... | @@ -22,17 +27,31 @@ | ... | @@ -22,17 +27,31 @@ |
| 22 | finished-text="没有更多了" | 27 | finished-text="没有更多了" |
| 23 | @load="onLoad" | 28 | @load="onLoad" |
| 24 | > | 29 | > |
| 25 | - <div v-for="item in list" :key="item" class="list-boxer"> | 30 | + <div v-for="item in list" :id="item.id" :key="item.id" class="list-boxer"> |
| 26 | <van-row align="center" justify="space-between"> | 31 | <van-row align="center" justify="space-between"> |
| 27 | <van-col span="16" style="display: flex;"> | 32 | <van-col span="16" style="display: flex;"> |
| 28 | - <van-icon name="passed" size="1.25rem" /> <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)">床垫 1.2m*2m</div> | 33 | + <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> |
| 34 | + <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> | ||
| 35 | + <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> | ||
| 36 | + {{ item.name }} | ||
| 37 | + </div> | ||
| 29 | </van-col> | 38 | </van-col> |
| 30 | <van-col span="8" style="display: flex; align-items: center;"> | 39 | <van-col span="8" style="display: flex; align-items: center;"> |
| 31 | - <van-field v-model="num_value" style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" label="" label-width="0" input-align="center" placeholder="数量" type="number" > | 40 | + <van-field |
| 41 | + v-model="item.num" | ||
| 42 | + style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;" | ||
| 43 | + label="" | ||
| 44 | + label-width="0" | ||
| 45 | + input-align="center" | ||
| 46 | + placeholder="数量" | ||
| 47 | + type="number" | ||
| 48 | + @blur="onBlur(item)" | ||
| 49 | + > | ||
| 32 | <template #left-icon></template> | 50 | <template #left-icon></template> |
| 33 | </van-field> <span style="font-size: 0.9rem; color: #666;">个</span> | 51 | </van-field> <span style="font-size: 0.9rem; color: #666;">个</span> |
| 34 | </van-col> | 52 | </van-col> |
| 35 | </van-row> | 53 | </van-row> |
| 54 | + <div v-if="item.error" style="padding: 0.5rem 2rem 0 0; font-size: 0.85rem; color: red; text-align: right;">输入值有误</div> | ||
| 36 | </div> | 55 | </div> |
| 37 | </van-list> | 56 | </van-list> |
| 38 | <div style="height: 6rem;"></div> | 57 | <div style="height: 6rem;"></div> |
| ... | @@ -46,11 +65,12 @@ | ... | @@ -46,11 +65,12 @@ |
| 46 | <div style="display: flex; align-items: center;"> | 65 | <div style="display: flex; align-items: center;"> |
| 47 | <van-button plain type="primary" :color="styleColor.baseColor" @click="addShoppingCart">加入购物车</van-button> | 66 | <van-button plain type="primary" :color="styleColor.baseColor" @click="addShoppingCart">加入购物车</van-button> |
| 48 | | 67 | |
| 49 | - <van-badge :content="5"> | 68 | + <van-badge :content="cart_count"> |
| 50 | <van-icon name="shopping-cart-o" size="2.5rem" :color="styleColor.baseColor" @click="goShoppingCart" /> | 69 | <van-icon name="shopping-cart-o" size="2.5rem" :color="styleColor.baseColor" @click="goShoppingCart" /> |
| 51 | </van-badge> | 70 | </van-badge> |
| 52 | </div> | 71 | </div> |
| 53 | </div> | 72 | </div> |
| 73 | + | ||
| 54 | </div> | 74 | </div> |
| 55 | 75 | ||
| 56 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> | 76 | <choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material> |
| ... | @@ -74,11 +94,58 @@ const $route = useRoute(); | ... | @@ -74,11 +94,58 @@ const $route = useRoute(); |
| 74 | const $router = useRouter(); | 94 | const $router = useRouter(); |
| 75 | useTitle($route.meta.title); | 95 | useTitle($route.meta.title); |
| 76 | 96 | ||
| 97 | +const is_all_checked = ref(false); | ||
| 77 | const num_value = ref(''); | 98 | const num_value = ref(''); |
| 78 | 99 | ||
| 100 | +const onCheckAll = () => { | ||
| 101 | + is_all_checked.value = !is_all_checked.value; | ||
| 102 | + if (is_all_checked.value) { | ||
| 103 | + list.value.forEach(item => { | ||
| 104 | + item.checked = true; | ||
| 105 | + }) | ||
| 106 | + } else { | ||
| 107 | + list.value.forEach(item => { | ||
| 108 | + item.checked = false; | ||
| 109 | + item.error = false; | ||
| 110 | + }) | ||
| 111 | + } | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +const onCheck = (item) => { | ||
| 115 | + item.checked = !item.checked; | ||
| 116 | + // 全部为选中 | ||
| 117 | + let all_checked = list.value.every((item) => item.checked === true); | ||
| 118 | + if (all_checked) { | ||
| 119 | + is_all_checked.value = true; | ||
| 120 | + } else { | ||
| 121 | + is_all_checked.value = false; | ||
| 122 | + } | ||
| 123 | + // 如果取消选中,隐藏错误提示 | ||
| 124 | + if (!item.checked) { | ||
| 125 | + item.error = false; | ||
| 126 | + } | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +const onBlur = (item) => { // 输入框失去焦点回调 | ||
| 130 | + if (item.checked) { | ||
| 131 | + if (item.num === null || item.num === '') { | ||
| 132 | + item.error = true; | ||
| 133 | + } else { | ||
| 134 | + item.error = false; | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | +} | ||
| 138 | + | ||
| 79 | const active = ref(0); | 139 | const active = ref(0); |
| 80 | -const onChange = (index) => { | 140 | +const onChange = (index) => { // 切换标签回调 |
| 81 | console.warn(index); | 141 | console.warn(index); |
| 142 | + // 取消全选 | ||
| 143 | + is_all_checked.value = false; | ||
| 144 | + // TODO:重新查询列表数据, 取消选中 | ||
| 145 | + list.value.forEach(item => { | ||
| 146 | + item.checked = false; | ||
| 147 | + item.error = false; | ||
| 148 | + }); | ||
| 82 | } | 149 | } |
| 83 | 150 | ||
| 84 | const list = ref([]); | 151 | const list = ref([]); |
| ... | @@ -90,7 +157,7 @@ const onLoad = () => { | ... | @@ -90,7 +157,7 @@ const onLoad = () => { |
| 90 | // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | 157 | // setTimeout 仅做示例,真实场景中一般为 ajax 请求 |
| 91 | setTimeout(() => { | 158 | setTimeout(() => { |
| 92 | for (let i = 0; i < 10; i++) { | 159 | for (let i = 0; i < 10; i++) { |
| 93 | - list.value.push(list.value.length + 1); | 160 | + list.value.push({ id: list.value.length + 1, name: '标题 床垫 1.2m*2m', num: null, checked: false, error: false }); |
| 94 | } | 161 | } |
| 95 | 162 | ||
| 96 | // 加载状态结束 | 163 | // 加载状态结束 |
| ... | @@ -101,6 +168,8 @@ const onLoad = () => { | ... | @@ -101,6 +168,8 @@ const onLoad = () => { |
| 101 | finished.value = true; | 168 | finished.value = true; |
| 102 | } | 169 | } |
| 103 | }, 1000); | 170 | }, 1000); |
| 171 | + // TODO: 如果查询到的数据大于0,需要取消全选 | ||
| 172 | + is_all_checked.value = false; | ||
| 104 | }; | 173 | }; |
| 105 | 174 | ||
| 106 | const onClickTitle = (item) => { // 点击物资标题回调 | 175 | const onClickTitle = (item) => { // 点击物资标题回调 |
| ... | @@ -113,8 +182,29 @@ const addMore = () => { // 添加更多 | ... | @@ -113,8 +182,29 @@ const addMore = () => { // 添加更多 |
| 113 | show_choose_material.value = true; | 182 | show_choose_material.value = true; |
| 114 | } | 183 | } |
| 115 | 184 | ||
| 185 | +const cart_count = ref(0); | ||
| 186 | +const shop_cart_list = ref([]); // 购物车列表 | ||
| 116 | const addShoppingCart = () => { // 加入购物车 | 187 | const addShoppingCart = () => { // 加入购物车 |
| 117 | - console.warn('addShoppingCart'); | 188 | + shop_cart_list.value = []; |
| 189 | + // 把选中的值集合 | ||
| 190 | + list.value | ||
| 191 | + .filter(item => item.checked) | ||
| 192 | + .forEach(item => { | ||
| 193 | + shop_cart_list.value = shop_cart_list.value.concat(item); | ||
| 194 | + }); | ||
| 195 | + // 校验购物车值 | ||
| 196 | + let error_list = shop_cart_list.value.filter((item) => { if (item.num === null || item.num === '') { return item;} }) | ||
| 197 | + if (error_list.length) { | ||
| 198 | + // 跳到第一个错误框 | ||
| 199 | + scrollToSection(error_list[0].id); | ||
| 200 | + // 标记所有错误 | ||
| 201 | + error_list.forEach(item => { | ||
| 202 | + item.error = true; | ||
| 203 | + }) | ||
| 204 | + return; | ||
| 205 | + } | ||
| 206 | + // 购物车数量 | ||
| 207 | + cart_count.value = shop_cart_list.value.length; | ||
| 118 | } | 208 | } |
| 119 | 209 | ||
| 120 | const goShoppingCart = () => { // 跳转购物车 | 210 | const goShoppingCart = () => { // 跳转购物车 |
| ... | @@ -131,6 +221,20 @@ const show_material_detail = ref(false); | ... | @@ -131,6 +221,20 @@ const show_material_detail = ref(false); |
| 131 | const onCloseDetail = () => { | 221 | const onCloseDetail = () => { |
| 132 | show_material_detail.value = false; | 222 | show_material_detail.value = false; |
| 133 | } | 223 | } |
| 224 | + | ||
| 225 | +const scrollToSection = (id) => { // 滚动到指定位置 | ||
| 226 | + const current_index = list.value.findIndex((item) => item.id === id); | ||
| 227 | + // 因为布局问题,需要滚动到上一个节点 查询上一个节点ID | ||
| 228 | + const previous_index = current_index - 2 >= 0 ? current_index - 2 : 0; | ||
| 229 | + nextTick(() => { | ||
| 230 | + let element = $('.list-wrapper').find(`#${list.value[previous_index]['id']}`); | ||
| 231 | + if (element[0]) { | ||
| 232 | + element[0].scrollIntoView({ behavior: 'smooth' }); | ||
| 233 | + } else { | ||
| 234 | + console.log('Element with ID ' + id + ' not found.'); | ||
| 235 | + } | ||
| 236 | + }) | ||
| 237 | +} | ||
| 134 | </script> | 238 | </script> |
| 135 | 239 | ||
| 136 | <style lang="less" scoped> | 240 | <style lang="less" scoped> | ... | ... |
-
Please register or login to post a comment