Showing
2 changed files
with
276 additions
and
48 deletions
src/components/chooseMaterial/_index.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2024-07-23 16:24:08 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2024-07-24 18:14:14 | ||
| 5 | + * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue | ||
| 6 | + * @Description: 选择物资组件 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="choose-material-page"> | ||
| 10 | + <van-popup | ||
| 11 | + v-model:show="showBottom" | ||
| 12 | + position="bottom" | ||
| 13 | + closeable | ||
| 14 | + @close="onClose" | ||
| 15 | + :style="{ height: '100%' }" | ||
| 16 | + > | ||
| 17 | + <van-sticky :offset-top="-33"> | ||
| 18 | + <div style="margin-top: 2rem; background-color: white;"> | ||
| 19 | + <div style="padding: 1rem;"> | ||
| 20 | + <van-row gutter="10" justify="center" align="center"> | ||
| 21 | + <van-col span="16"> | ||
| 22 | + <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;"> | ||
| 23 | + <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资" style="background-color: #FBF9F1;" /> | ||
| 24 | + </div> | ||
| 25 | + </van-col> | ||
| 26 | + <van-col span="8"> | ||
| 27 | + <div @click="showType" style="border-radius: 8px; border: 1px solid #DBDBDB; padding: 0.5rem 0 0.5rem 1rem; font-size: 0.9rem; color: #B4B4B4;"> | ||
| 28 | + 物资分类 | ||
| 29 | + <van-icon name="arrow-down" color="#A67939" /> | ||
| 30 | + </div> | ||
| 31 | + </van-col> | ||
| 32 | + </van-row> | ||
| 33 | + </div> | ||
| 34 | + </div> | ||
| 35 | + </van-sticky> | ||
| 36 | + <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 --> | ||
| 37 | + <van-list | ||
| 38 | + v-model:loading="loading" | ||
| 39 | + :finished="finished" | ||
| 40 | + finished-text="没有更多了" | ||
| 41 | + @load="onLoad" | ||
| 42 | + > | ||
| 43 | + <div v-for="item in list" :key="item" > | ||
| 44 | + <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;"> | ||
| 45 | + <van-col span="8" @click="onCheckAll(item)"> | ||
| 46 | + <van-icon v-if="item.checked" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 47 | + <van-icon v-else name="passed" size="1.25rem" /> | ||
| 48 | + <span :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 49 | + </van-col> | ||
| 50 | + <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">{{ item.name }}</van-col> | ||
| 51 | + <van-col span="8"></van-col> | ||
| 52 | + </van-row> | ||
| 53 | + <van-row align="center" justify="space-between" style=""> | ||
| 54 | + <van-col v-for="m in item.m_list" :key="m.id" span="24" style="display: flex; padding: 1rem; border-bottom: 1px solid #F5F5F5;"> | ||
| 55 | + <van-icon v-if="m.checked" @click="onCheck(item, m)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 56 | + <van-icon v-else name="passed" @click="onCheck(item, m)" size="1.25rem" /> | ||
| 57 | + <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(m)"> | ||
| 58 | + {{ m.name }} | ||
| 59 | + </div> | ||
| 60 | + </van-col> | ||
| 61 | + </van-row> | ||
| 62 | + </div> | ||
| 63 | + </van-list> | ||
| 64 | + <div style="height: 6rem;"></div> | ||
| 65 | + <div class="control-bar"> | ||
| 66 | + <van-button plain block type="primary" :color="styleColor.baseColor" @click="addShoppingCart">加入购物车</van-button> | ||
| 67 | + <div style="display: flex; align-items: center; margin-left: 1rem;"> | ||
| 68 | + <van-badge :content="cart_count"> | ||
| 69 | + <van-icon name="shopping-cart-o" size="2.5rem" :color="styleColor.baseColor" @click="goShoppingCart" /> | ||
| 70 | + </van-badge> | ||
| 71 | + </div> | ||
| 72 | + </div> | ||
| 73 | + <van-back-top class="custom" bottom="12vh" z-index="9999">返回顶部</van-back-top> | ||
| 74 | + <van-dialog v-model:show="show_type" title="请选择筛选分类" @confirm="onConfirm" show-cancel-button :confirm-button-color="styleColor.baseColor"> | ||
| 75 | + <div style="padding: 1rem;"> | ||
| 76 | + <van-checkbox-group v-model="type_checked" shape="square" direction="horizontal" :checked-color="styleColor.baseColor"> | ||
| 77 | + <van-checkbox name="a" style="margin-bottom: 0.5rem;">复选框 a</van-checkbox> | ||
| 78 | + <van-checkbox name="b" style="margin-bottom: 0.5rem;">复选框 b</van-checkbox> | ||
| 79 | + <van-checkbox name="c" style="margin-bottom: 0.5rem;">复选框 c</van-checkbox> | ||
| 80 | + <van-checkbox name="d" style="margin-bottom: 0.5rem;">复选框 d</van-checkbox> | ||
| 81 | + </van-checkbox-group> | ||
| 82 | + </div> | ||
| 83 | + </van-dialog> | ||
| 84 | + </van-popup> | ||
| 85 | + </div> | ||
| 86 | + | ||
| 87 | + <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail> | ||
| 88 | + | ||
| 89 | +</template> | ||
| 90 | + | ||
| 91 | +<script setup> | ||
| 92 | +import { ref } from 'vue' | ||
| 93 | +import { useRoute, useRouter } from 'vue-router' | ||
| 94 | +import { showToast } from 'vant'; | ||
| 95 | +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js' | ||
| 96 | +//import { } from '@/utils/generateModules.js' | ||
| 97 | +//import { } from '@/utils/generateIcons.js' | ||
| 98 | +//import { } from '@/composables' | ||
| 99 | +import { styleColor } from "@/constant.js"; | ||
| 100 | +import materialDetail from '@/components/materialDetail/index.vue'; | ||
| 101 | + | ||
| 102 | +const $route = useRoute(); | ||
| 103 | +const $router = useRouter(); | ||
| 104 | +useTitle($route.meta.title); | ||
| 105 | + | ||
| 106 | +const props = defineProps({ | ||
| 107 | + show: Boolean, | ||
| 108 | +}); | ||
| 109 | +const emit = defineEmits(['close']); | ||
| 110 | + | ||
| 111 | +const showBottom = ref(false); | ||
| 112 | + | ||
| 113 | +onMounted(() => { | ||
| 114 | +}); | ||
| 115 | + | ||
| 116 | +// 监听字段变化 | ||
| 117 | +watch( | ||
| 118 | + () => props.show, | ||
| 119 | + (v) => { | ||
| 120 | + showBottom.value = v; | ||
| 121 | + } | ||
| 122 | +); | ||
| 123 | + | ||
| 124 | +const onClose = () => { | ||
| 125 | + emit('close'); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +const list = ref([]); | ||
| 129 | +const loading = ref(false); | ||
| 130 | +const finished = ref(false); | ||
| 131 | + | ||
| 132 | +const onLoad = () => { | ||
| 133 | + // 异步更新数据 | ||
| 134 | + // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | ||
| 135 | + setTimeout(() => { | ||
| 136 | + for (let i = 0; i < 5; i++) { | ||
| 137 | + list.value.push({ id: i, name: '物资分类' + i, checked: false, m_list: [] }); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + list.value.forEach((item) => { | ||
| 141 | + for (let j = 0; j < 5; j++) { | ||
| 142 | + item.m_list.push({ id: j, name: '标题' + j, checked: false }); | ||
| 143 | + } | ||
| 144 | + }) | ||
| 145 | + | ||
| 146 | + // 加载状态结束 | ||
| 147 | + loading.value = false; | ||
| 148 | + | ||
| 149 | + // 数据全部加载完成 | ||
| 150 | + if (list.value.length >= 40) { | ||
| 151 | + finished.value = true; | ||
| 152 | + } | ||
| 153 | + }, 1000); | ||
| 154 | +}; | ||
| 155 | + | ||
| 156 | +const onClickTitle = (item) => { // 点击物资标题回调 | ||
| 157 | + console.warn(item); | ||
| 158 | + show_material_detail.value = true; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +const show_type = ref(false); | ||
| 162 | +const showType = () => { | ||
| 163 | + show_type.value = true; | ||
| 164 | +} | ||
| 165 | +const type_checked = ref([]); | ||
| 166 | +const onConfirm = () => { | ||
| 167 | + console.warn(type_checked.value); | ||
| 168 | +} | ||
| 169 | + | ||
| 170 | +const search_value = ref(''); | ||
| 171 | +const onBlur = () => { | ||
| 172 | + // TODO: 输入框失去焦点,接口需要一个搜索接口,返回相应的值 | ||
| 173 | + console.warn(search_value.value); | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +const show_material_detail = ref(false); | ||
| 177 | +const onCloseDetail = () => { // 关闭物资详情窗口 | ||
| 178 | + show_material_detail.value = false; | ||
| 179 | +} | ||
| 180 | + | ||
| 181 | +const onCheckAll = (item) => { // 全选分类 | ||
| 182 | + item.checked = !item.checked; | ||
| 183 | + item.m_list.forEach((m) => { | ||
| 184 | + m.checked = item.checked; | ||
| 185 | + }); | ||
| 186 | +} | ||
| 187 | +const onCheck = (item, m) => { // 选中单个物资 | ||
| 188 | + m.checked = !m.checked; | ||
| 189 | + item.checked = item.m_list.every(m => m.checked); | ||
| 190 | +} | ||
| 191 | + | ||
| 192 | +const addShoppingCart = () => { // 新增购物车 | ||
| 193 | + shop_cart_list.value = []; | ||
| 194 | + list.value.forEach(item => { | ||
| 195 | + item.m_list.forEach(m => { | ||
| 196 | + if (m.checked) { | ||
| 197 | + shop_cart_list.value.push(m); | ||
| 198 | + } | ||
| 199 | + }) | ||
| 200 | + }); | ||
| 201 | + // 购物车为空提示 | ||
| 202 | + if (!shop_cart_list.value.length) { | ||
| 203 | + showToast('请选择物资'); | ||
| 204 | + return; | ||
| 205 | + } | ||
| 206 | + // TODO: 请求购物车接口,更新购物车数量 | ||
| 207 | + console.warn(shop_cart_list.value); | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +const goShoppingCart = () => { // 点击购物车图标 | ||
| 211 | + if ($route.path === '/material_pre_request') { // 待申领物资页面 | ||
| 212 | + onClose() | ||
| 213 | + } else { | ||
| 214 | + $router.push({ path: '/material_pre_request' }); | ||
| 215 | + } | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +const cart_count = ref(0); // 购物车数量 | ||
| 219 | + | ||
| 220 | +const shop_cart_list = ref([]); // 购物车列表 | ||
| 221 | +</script> | ||
| 222 | + | ||
| 223 | +<style lang="less"> | ||
| 224 | +.choose-material-page { | ||
| 225 | + .control-bar { | ||
| 226 | + display: flex; position: fixed; padding: 1rem 1.5rem; left: 0; right: 0; bottom: 0; background-color: white; width: calc(100% - 3rem); justify-content: space-between; align-items: center; box-shadow: 0rem -0.33rem 0.33rem 0.08rem rgba(0,0,0,0.06); | ||
| 227 | + } | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +.custom { | ||
| 231 | + width: 80px; | ||
| 232 | + font-size: 14px; | ||
| 233 | + text-align: center; | ||
| 234 | + background-color: #A67939; | ||
| 235 | +} | ||
| 236 | +</style> |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-23 16:24:08 | 2 | * @Date: 2024-07-23 16:24:08 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-07-24 18:14:14 | 4 | + * @LastEditTime: 2024-07-25 13:32:12 |
| 5 | * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue | 5 | * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue |
| 6 | * @Description: 选择物资组件 | 6 | * @Description: 选择物资组件 |
| 7 | --> | 7 | --> |
| ... | @@ -18,22 +18,25 @@ | ... | @@ -18,22 +18,25 @@ |
| 18 | <div style="margin-top: 2rem; background-color: white;"> | 18 | <div style="margin-top: 2rem; background-color: white;"> |
| 19 | <div style="padding: 1rem;"> | 19 | <div style="padding: 1rem;"> |
| 20 | <van-row gutter="10" justify="center" align="center"> | 20 | <van-row gutter="10" justify="center" align="center"> |
| 21 | - <van-col span="16"> | 21 | + <van-col span="24"> |
| 22 | <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;"> | 22 | <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;"> |
| 23 | <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资" style="background-color: #FBF9F1;" /> | 23 | <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资" style="background-color: #FBF9F1;" /> |
| 24 | </div> | 24 | </div> |
| 25 | </van-col> | 25 | </van-col> |
| 26 | - <van-col span="8"> | ||
| 27 | - <div @click="showType" style="border-radius: 8px; border: 1px solid #DBDBDB; padding: 0.5rem 0 0.5rem 1rem; font-size: 0.9rem; color: #B4B4B4;"> | ||
| 28 | - 物资分类 | ||
| 29 | - <van-icon name="arrow-down" color="#A67939" /> | ||
| 30 | - </div> | ||
| 31 | - </van-col> | ||
| 32 | </van-row> | 26 | </van-row> |
| 33 | </div> | 27 | </div> |
| 34 | </div> | 28 | </div> |
| 35 | </van-sticky> | 29 | </van-sticky> |
| 36 | <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 --> | 30 | <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 --> |
| 31 | + <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;"> | ||
| 32 | + <van-col span="8" @click="onCheckAll()"> | ||
| 33 | + <van-icon v-if="is_all_checked" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 34 | + <van-icon v-else name="passed" size="1.25rem" /> | ||
| 35 | + <span :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 36 | + </van-col> | ||
| 37 | + <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">选择物资</van-col> | ||
| 38 | + <van-col span="8"></van-col> | ||
| 39 | + </van-row> | ||
| 37 | <van-list | 40 | <van-list |
| 38 | v-model:loading="loading" | 41 | v-model:loading="loading" |
| 39 | :finished="finished" | 42 | :finished="finished" |
| ... | @@ -41,21 +44,12 @@ | ... | @@ -41,21 +44,12 @@ |
| 41 | @load="onLoad" | 44 | @load="onLoad" |
| 42 | > | 45 | > |
| 43 | <div v-for="item in list" :key="item" > | 46 | <div v-for="item in list" :key="item" > |
| 44 | - <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;"> | ||
| 45 | - <van-col span="8" @click="onCheckAll(item)"> | ||
| 46 | - <van-icon v-if="item.checked" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | ||
| 47 | - <van-icon v-else name="passed" size="1.25rem" /> | ||
| 48 | - <span :style="{ color: styleColor.baseColor }"> 全选</span> | ||
| 49 | - </van-col> | ||
| 50 | - <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">{{ item.name }}</van-col> | ||
| 51 | - <van-col span="8"></van-col> | ||
| 52 | - </van-row> | ||
| 53 | <van-row align="center" justify="space-between" style=""> | 47 | <van-row align="center" justify="space-between" style=""> |
| 54 | - <van-col v-for="m in item.m_list" :key="m.id" span="24" style="display: flex; padding: 1rem; border-bottom: 1px solid #F5F5F5;"> | 48 | + <van-col span="24" style="display: flex; padding: 1rem; border-bottom: 1px solid #F5F5F5;"> |
| 55 | - <van-icon v-if="m.checked" @click="onCheck(item, m)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> | 49 | + <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" /> |
| 56 | - <van-icon v-else name="passed" @click="onCheck(item, m)" size="1.25rem" /> | 50 | + <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" /> |
| 57 | - <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(m)"> | 51 | + <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)"> |
| 58 | - {{ m.name }} | 52 | + {{ item.name }} |
| 59 | </div> | 53 | </div> |
| 60 | </van-col> | 54 | </van-col> |
| 61 | </van-row> | 55 | </van-row> |
| ... | @@ -71,16 +65,6 @@ | ... | @@ -71,16 +65,6 @@ |
| 71 | </div> | 65 | </div> |
| 72 | </div> | 66 | </div> |
| 73 | <van-back-top class="custom" bottom="12vh" z-index="9999">返回顶部</van-back-top> | 67 | <van-back-top class="custom" bottom="12vh" z-index="9999">返回顶部</van-back-top> |
| 74 | - <van-dialog v-model:show="show_type" title="请选择筛选分类" @confirm="onConfirm" show-cancel-button :confirm-button-color="styleColor.baseColor"> | ||
| 75 | - <div style="padding: 1rem;"> | ||
| 76 | - <van-checkbox-group v-model="type_checked" shape="square" direction="horizontal" :checked-color="styleColor.baseColor"> | ||
| 77 | - <van-checkbox name="a" style="margin-bottom: 0.5rem;">复选框 a</van-checkbox> | ||
| 78 | - <van-checkbox name="b" style="margin-bottom: 0.5rem;">复选框 b</van-checkbox> | ||
| 79 | - <van-checkbox name="c" style="margin-bottom: 0.5rem;">复选框 c</van-checkbox> | ||
| 80 | - <van-checkbox name="d" style="margin-bottom: 0.5rem;">复选框 d</van-checkbox> | ||
| 81 | - </van-checkbox-group> | ||
| 82 | - </div> | ||
| 83 | - </van-dialog> | ||
| 84 | </van-popup> | 68 | </van-popup> |
| 85 | </div> | 69 | </div> |
| 86 | 70 | ||
| ... | @@ -134,20 +118,14 @@ const onLoad = () => { | ... | @@ -134,20 +118,14 @@ const onLoad = () => { |
| 134 | // setTimeout 仅做示例,真实场景中一般为 ajax 请求 | 118 | // setTimeout 仅做示例,真实场景中一般为 ajax 请求 |
| 135 | setTimeout(() => { | 119 | setTimeout(() => { |
| 136 | for (let i = 0; i < 5; i++) { | 120 | for (let i = 0; i < 5; i++) { |
| 137 | - list.value.push({ id: i, name: '物资分类' + i, checked: false, m_list: [] }); | 121 | + list.value.push({ id: i, name: '物资' + i, checked: false }); |
| 138 | } | 122 | } |
| 139 | 123 | ||
| 140 | - list.value.forEach((item) => { | ||
| 141 | - for (let j = 0; j < 5; j++) { | ||
| 142 | - item.m_list.push({ id: j, name: '标题' + j, checked: false }); | ||
| 143 | - } | ||
| 144 | - }) | ||
| 145 | - | ||
| 146 | // 加载状态结束 | 124 | // 加载状态结束 |
| 147 | loading.value = false; | 125 | loading.value = false; |
| 148 | 126 | ||
| 149 | // 数据全部加载完成 | 127 | // 数据全部加载完成 |
| 150 | - if (list.value.length >= 40) { | 128 | + if (list.value.length >= 10) { |
| 151 | finished.value = true; | 129 | finished.value = true; |
| 152 | } | 130 | } |
| 153 | }, 1000); | 131 | }, 1000); |
| ... | @@ -178,15 +156,29 @@ const onCloseDetail = () => { // 关闭物资详情窗口 | ... | @@ -178,15 +156,29 @@ const onCloseDetail = () => { // 关闭物资详情窗口 |
| 178 | show_material_detail.value = false; | 156 | show_material_detail.value = false; |
| 179 | } | 157 | } |
| 180 | 158 | ||
| 181 | -const onCheckAll = (item) => { // 全选分类 | 159 | +const is_all_checked = ref(false); |
| 182 | - item.checked = !item.checked; | 160 | +const onCheckAll = () => { |
| 183 | - item.m_list.forEach((m) => { | 161 | + is_all_checked.value = !is_all_checked.value; |
| 184 | - m.checked = item.checked; | 162 | + if (is_all_checked.value) { |
| 185 | - }); | 163 | + list.value.forEach(item => { |
| 164 | + item.checked = true; | ||
| 165 | + }) | ||
| 166 | + } else { | ||
| 167 | + list.value.forEach(item => { | ||
| 168 | + item.checked = false; | ||
| 169 | + item.error = false; | ||
| 170 | + }) | ||
| 171 | + } | ||
| 186 | } | 172 | } |
| 187 | -const onCheck = (item, m) => { // 选中单个物资 | 173 | +const onCheck = (item) => { |
| 188 | - m.checked = !m.checked; | 174 | + item.checked = !item.checked; |
| 189 | - item.checked = item.m_list.every(m => m.checked); | 175 | + // 全部为选中 |
| 176 | + let all_checked = list.value.every((item) => item.checked === true); | ||
| 177 | + if (all_checked) { | ||
| 178 | + is_all_checked.value = true; | ||
| 179 | + } else { | ||
| 180 | + is_all_checked.value = false; | ||
| 181 | + } | ||
| 190 | } | 182 | } |
| 191 | 183 | ||
| 192 | const addShoppingCart = () => { // 新增购物车 | 184 | const addShoppingCart = () => { // 新增购物车 | ... | ... |
-
Please register or login to post a comment