index.vue 7.02 KB
<!--
 * @Date: 2024-07-23 16:24:08
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2024-07-25 13:32:12
 * @FilePath: /temple_material_request/src/components/chooseMaterial/index.vue
 * @Description: 选择物资组件
-->
<template>
  <div class="choose-material-page">
    <van-popup
      v-model:show="showBottom"
      position="bottom"
      closeable
      @close="onClose"
      :style="{ height: '100%' }"
    >
      <van-sticky  :offset-top="-33">
        <div style="margin-top: 2rem; background-color: white;">
            <div style="padding: 1rem;">
              <van-row gutter="10" justify="center" align="center">
                <van-col span="24">
                  <div style="background-color: #FBF9F1; display: flex; border-radius: 5rem; padding: 0 1rem; align-items: center; justify-content: center;">
                    <van-icon name="search" /><van-field v-model="search_value" @blur="onBlur" label="" placeholder="搜索物资" style="background-color: #FBF9F1;" />
                  </div>
                </van-col>
              </van-row>
            </div>
        </div>
      </van-sticky>
      <!-- TODO:物资列表显示值需要过滤掉购物车已经选中的物资,新增的物资需要显示在购物车最上面 -->
      <van-row justify="space-around" align="center" style="padding: 1rem; background-color: #F2F2F2;">
        <van-col span="8" @click="onCheckAll()">
          <van-icon v-if="is_all_checked" name="checked" size="1.25rem" :color="styleColor.baseColor" />
          <van-icon v-else name="passed" size="1.25rem" />
          <span :style="{ color: styleColor.baseColor }">&nbsp;&nbsp;全选</span>
        </van-col>
        <van-col span="8" style="text-align: center; font-size: 0.95rem; color: #666666; font-weight: bold;">选择物资</van-col>
        <van-col span="8"></van-col>
      </van-row>
      <van-list
        v-model:loading="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="onLoad"
      >
        <div v-for="item in list" :key="item" >
          <van-row align="center" justify="space-between" style="">
            <van-col span="24" style="display: flex; padding: 1rem; border-bottom: 1px solid #F5F5F5;">
              <van-icon v-if="item.checked" @click="onCheck(item)" name="checked" size="1.25rem" :color="styleColor.baseColor" />
              <van-icon v-else name="passed" @click="onCheck(item)" size="1.25rem" />&nbsp;&nbsp;
              <div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)">
                {{ item.name }}
              </div>
            </van-col>
          </van-row>
        </div>
      </van-list>
      <div style="height: 6rem;"></div>
      <div class="control-bar">
        <van-button plain block type="primary" :color="styleColor.baseColor" @click="addShoppingCart">加入购物车</van-button>
        <div style="display: flex; align-items: center; margin-left: 1rem;">
          <van-badge :content="cart_count">
            <van-icon name="shopping-cart-o" size="2.5rem" :color="styleColor.baseColor" @click="goShoppingCart" />
          </van-badge>
        </div>
      </div>
      <van-back-top class="custom" bottom="12vh"  z-index="9999">返回顶部</van-back-top>
    </van-popup>
  </div>

  <material-detail :show="show_material_detail" @close="onCloseDetail"></material-detail>

</template>

<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { showToast } from 'vant';
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { styleColor } from "@/constant.js";
import materialDetail from '@/components/materialDetail/index.vue';

const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);

const props = defineProps({
  show: Boolean,
});
const emit = defineEmits(['close']);

const showBottom = ref(false);

onMounted(() => {
});

// 监听字段变化
watch(
  () => props.show,
  (v) => {
    showBottom.value = v;
  }
);

const onClose = () => {
  emit('close');
}

const list = ref([]);
const loading = ref(false);
const finished = ref(false);

const onLoad = () => {
  // 异步更新数据
  // setTimeout 仅做示例,真实场景中一般为 ajax 请求
  setTimeout(() => {
    for (let i = 0; i < 5; i++) {
      list.value.push({ id: i, name: '物资' + i, checked: false });
    }

    // 加载状态结束
    loading.value = false;

    // 数据全部加载完成
    if (list.value.length >= 10) {
      finished.value = true;
    }
  }, 1000);
};

const onClickTitle = (item) => { // 点击物资标题回调
  console.warn(item);
  show_material_detail.value = true;
}

const show_type = ref(false);
const showType = () => {
  show_type.value = true;
}
const type_checked = ref([]);
const onConfirm = () => {
  console.warn(type_checked.value);
}

const search_value = ref('');
const onBlur = () => {
  // TODO: 输入框失去焦点,接口需要一个搜索接口,返回相应的值
  console.warn(search_value.value);
}

const show_material_detail = ref(false);
const onCloseDetail = () => { // 关闭物资详情窗口
  show_material_detail.value = false;
}

const is_all_checked = ref(false);
const onCheckAll = () => {
  is_all_checked.value = !is_all_checked.value;
  if (is_all_checked.value) {
    list.value.forEach(item => {
      item.checked = true;
    })
  } else {
    list.value.forEach(item => {
      item.checked = false;
      item.error = false;
    })
  }
}
const onCheck = (item) => {
  item.checked = !item.checked;
  // 全部为选中
  let all_checked = list.value.every((item) => item.checked === true);
  if (all_checked) {
    is_all_checked.value = true;
  } else {
    is_all_checked.value = false;
  }
}

const addShoppingCart = () => { // 新增购物车
  shop_cart_list.value = [];
  list.value.forEach(item => {
    item.m_list.forEach(m => {
      if (m.checked) {
        shop_cart_list.value.push(m);
      }
    })
  });
  // 购物车为空提示
  if (!shop_cart_list.value.length) {
    showToast('请选择物资');
    return;
  }
  // TODO: 请求购物车接口,更新购物车数量
  console.warn(shop_cart_list.value);
}

const goShoppingCart = () => { // 点击购物车图标
  if ($route.path === '/material_pre_request') { // 待申领物资页面
    onClose()
  } else {
    $router.push({ path: '/material_pre_request' });
  }
}

const cart_count = ref(0); // 购物车数量

const shop_cart_list = ref([]); // 购物车列表
</script>

<style lang="less">
.choose-material-page {
  .control-bar {
    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);
  }
}

.custom {
  width: 80px;
  font-size: 14px;
  text-align: center;
  background-color: #A67939;
}
</style>