hookehuyr

待申领物资-购物车操作逻辑完善

<!--
* @Date: 2024-07-23 12:53:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-24 11:21:02
* @LastEditTime: 2024-07-24 16:52:35
* @FilePath: /temple_material_request/src/views/material_pre_request.vue
* @Description: 待申领物资页面
-->
......@@ -12,13 +12,20 @@
<van-row justify="space-between" class="select-all-item">
<van-col span="8">
<!-- TODO:编辑模式下,不能确认申请 -->
<van-icon name="passed" size="1.25rem" />&nbsp;&nbsp;<span :style="{ color: styleColor.baseColor }">全选</span>
<span v-if="model === 'edit'">
<van-icon v-if="is_all_checked" @click="onCheckAll()" name="checked" size="1.25rem" :color="styleColor.baseColor" />
<van-icon v-else name="passed" @click="onCheckAll()" size="1.25rem" />
<span @click="onCheckAll()" :style="{ color: styleColor.baseColor }">&nbsp;&nbsp;全选</span>
</span>
<!-- TODO:非编辑模式下,显示购物车总数量 -->
<span :style="{ color: styleColor.baseColor }">品项数: 1000</span>
<span v-else :style="{ color: styleColor.baseColor }">品项数: {{ sum_num }}</span>
</van-col>
<van-col span="16" :style="{ textAlign: 'right', fontSize: '0.85rem', color: styleColor.baseColor }">
<van-icon name="records-o" />&nbsp;编辑
<van-icon name="delete-o" />&nbsp;删除
<span v-if="model !== 'edit'" @click="onClickEdit"><van-icon name="records-o" />&nbsp;编辑</span>
<span v-else>
<span @click="onClickDel"><van-icon name="delete-o" />&nbsp;删除</span>&nbsp;&nbsp;
<span @click="onClickCancel"><van-icon name="close" />&nbsp;取消编辑</span>
</span>
</van-col>
</van-row>
</van-sticky>
......@@ -28,17 +35,34 @@
finished-text="没有更多了"
@load="onLoad"
>
<div v-for="item in list" :key="item" class="list-boxer">
<div v-for="item in list" :id="item.id" :key="item" class="list-boxer">
<van-row align="center" justify="space-between">
<van-col span="16" style="display: flex;">
<van-icon name="passed" size="1.25rem" />&nbsp;&nbsp;<div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)">床垫 1.2m*2m</div>
<span v-if="item.edit">
<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;
</span>
<div class="van-ellipsis" :style="{ color: styleColor.baseColor, textDecoration: 'underline' }" @click="onClickTitle(item)">
{{ item.name }}
</div>
</van-col>
<van-col span="8" style="display: flex; align-items: center;">
<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" >
<van-field
v-model="item.num"
style="border: 1px solid #f0f0f0; padding: 0; border-radius: 5px;"
label=""
label-width="0"
input-align="center"
placeholder="数量"
type="number"
:disabled="!item.edit"
@blur="onBlur(item)"
>
<template #left-icon></template>
</van-field>&nbsp;&nbsp;<span style="font-size: 0.9rem; color: #666;">个</span>
</van-col>
</van-row>
<div v-if="item.error" style="padding: 0.5rem 2rem 0 0; font-size: 0.85rem; color: red; text-align: right;">输入值有误</div>
</div>
</van-list>
<div style="height: 6rem;"></div>
......@@ -72,7 +96,7 @@
/>
</van-popup>
<van-dialog v-model:show="showType" @confirm="onDialogConfirm" title="" show-cancel-button :confirm-button-color="styleColor.baseColor">
<van-dialog v-model:show="showType" title="" :show-cancel-button="false" :show-confirm-button="false">
<div style="padding: 1.5rem 0 0; text-align: center; font-size: 0.95rem; font-weight: bold;">请确认您本次是为哪个组别申领物资</div>
<div style="display: flex; align-items: center; padding: 1rem;">
<!-- <div style="font-size: 0.9rem; margin-right: 1rem; width: 5rem;">申领组:&nbsp;&nbsp;</div> -->
......@@ -86,14 +110,22 @@
</div>
<div style="padding: 0 1rem;">
<van-row gutter="10" align="center" style="margin-bottom: 0.5rem;">
<van-col span="7" style="text-align: right;">申领人:</van-col>
<van-col span="17"><van-field v-model="value" label="" placeholder="请输入" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col>
<van-col span="7" style="text-align: right;"><span style="color: red;">*</span>申领人:</van-col>
<van-col span="17"><van-field v-model="request_user" label="" placeholder="请输入" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col>
</van-row>
<van-row gutter="10" align="center" style="margin-bottom: 1rem;">
<van-col span="7" style="text-align: right;">联系电话:</van-col>
<van-col span="17"><van-field v-model="value" label="" placeholder="请输入" type="number" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col>
<van-col span="7" style="text-align: right;"><span style="color: red;">*</span>联系电话:</van-col>
<van-col span="17"><van-field v-model="request_tel" label="" placeholder="请输入" type="number" style="border: 1px solid #DBDBDB; padding: 0.25rem 1rem; border-radius: 5px;" /></van-col>
</van-row>
</div>
<van-row gutter="20" justify="space-around" align="center" style="padding: 1rem; border-top: 1px solid #E9E9E9; text-align: center;">
<van-col span="12">
<van-button plain block color="#A67939" @click="onDialogCancel">取消</van-button>
</van-col>
<van-col span="12">
<van-button block color="#A67939" @click="onDialogConfirm">确定</van-button>
</van-col>
</van-row>
</van-dialog>
<choose-material :show="show_choose_material" @close="onCloseChoose"></choose-material>
......@@ -104,7 +136,7 @@
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { showToast, showConfirmDialog } from 'vant';
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
......@@ -118,7 +150,100 @@ const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const num_value = ref('');
const is_all_checked = ref(false);
const sum_num = ref(999); // TODO: 品项的总数量,需要接口提供
const model = ref(''); // 默认非编辑模式
const onClickEdit = () => { // 点击编辑
model.value = 'edit';
list.value.forEach(item => {
item.checked = false;
item.error = false;
item.edit = true;
})
}
const onClickDel = () => { // 点击删除
let shop_cart_list = [];
// 把选中的值集合
list.value
.filter(item => item.checked)
.forEach(item => {
shop_cart_list = shop_cart_list.concat(item);
});
// 购物车为空提示
if (!shop_cart_list.length) {
showToast('删除项为空');
return;
}
// TODO:删除选中的项,接口需要一个购物车删除指定ID的接口
let del_ids = shop_cart_list.map(item => item.id);
console.warn(del_ids);
showConfirmDialog({
title: '温馨提示',
message:
`您是否需要删除这 ${del_ids.length} 项物资?`,
confirmButtonColor: styleColor.baseColor,
})
.then(() => {
// on confirm
// 还原列表显示
onClickCancel();
// TODO: 刷新列表
})
.catch(() => {
// on cancel
});
}
const onClickCancel = () => { // 点击取消
if (checkShoppingCart()) {
model.value = '';
is_all_checked.value = false;
list.value.forEach(item => {
item.error = false;
item.edit = 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;
}
// 如果取消选中,隐藏错误提示
if (!item.checked) {
item.error = false;
}
}
const onBlur = (item) => { // 输入框失去焦点回调
if (item.num === null || item.num === '') {
item.error = true;
} else {
item.error = false;
}
// TODO: 输入框失去焦点,接口需要一个购物车更新接口
}
const list = ref([]);
const loading = ref(false);
......@@ -129,7 +254,7 @@ const onLoad = () => {
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
setTimeout(() => {
for (let i = 0; i < 10; i++) {
list.value.push(list.value.length + 1);
list.value.push({ id: list.value.length + 1, name: '标题 床垫 1.2m*2m', num: 11, checked: false, error: false, edit: model.value === 'edit' });
}
// 加载状态结束
......@@ -140,6 +265,8 @@ const onLoad = () => {
finished.value = true;
}
}, 1000);
// TODO: 如果查询到的数据大于0,需要取消全选
is_all_checked.value = false;
};
const onClickTitle = (item) => { // 点击物资标题回调
......@@ -168,25 +295,81 @@ const addMore = () => { // 添加更多回调
show_choose_material.value = true;
}
const shop_cart_list = ref([]); // 购物车列表
const checkShoppingCart = () => { // 检查购物车有效性
let flag = true;
// 校验购物车值
let error_list = list.value.filter((item) => { if (item.num === null || item.num === '') { return item;} })
if (error_list.length) {
// 跳到第一个错误框
scrollToSection(error_list[0].id);
// 标记所有错误
error_list.forEach(item => {
item.error = true;
});
flag = false
return;
}
return flag;
}
const onConfirmRequest = () => { // 确定申领回调
console.warn('onConfirmRequest');
if (!use_date.value) {
showToast('请选择使用日期');
return;
}
showType.value = true;
}
const showType = ref(false);
const type_checked = ref('');
const scrollToSection = (id) => { // 滚动到指定位置
const current_index = list.value.findIndex((item) => item.id === id);
// 因为布局问题,需要滚动到上一个节点 查询上一个节点ID
const previous_index = current_index - 2 >= 0 ? current_index - 2 : 0;
nextTick(() => {
let element = $('.list-wrapper').find(`#${list.value[previous_index]['id']}`);
if (element[0]) {
element[0].scrollIntoView({ behavior: 'smooth' });
} else {
console.log('Element with ID ' + id + ' not found.');
}
})
}
const showType = ref(false);
const type_checked = ref(''); // 组别
const request_user = ref(''); // 申领人
const request_tel = ref(''); // 联系电话
const onDialogConfirm = () => {
console.warn(type_checked.value);
if (!type_checked.value) {
showToast('请选择组别')
}
if (!request_user.value) {
showToast('申领人不能为空')
}
if (!request_tel.value) {
showToast('联系电话不能为空')
}
console.warn('组别', type_checked.value);
console.warn('use_date', use_date.value);
console.warn('request_user', request_user.value);
console.warn('request_tel', request_tel.value);
// TODO:购物车的值应该不用传,数量应该是单独修改
showType.value = false;
}
const onDialogCancel = () => {
showType.value = false;
}
const show_choose_material = ref(false);
const onCloseChoose = () => {
const onCloseChoose = () => { // 关闭选择物资弹窗回调
// TODO: 需要刷新列表,应该可能新增的物料
show_choose_material.value = false;
}
const show_material_detail = ref(false);
const onCloseDetail = () => {
const onCloseDetail = () => { // 关闭物资详情窗口
show_material_detail.value = false;
}
</script>
......
<!--
* @Date: 2024-07-23 12:53:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-24 14:44:31
* @LastEditTime: 2024-07-24 15:15:38
* @FilePath: /temple_material_request/src/views/material_request.vue
* @Description: 申领物资页面
-->
<template>
<div class="material-request-page">
<van-tabs v-model:active="active" @change="onChange" sticky :color="styleColor.baseColor">
<van-tab v-for="index in 8" :title="'标签 ' + index">
<div class="list-wrapper">
......@@ -81,7 +80,7 @@
<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'
......@@ -192,6 +191,11 @@ const addShoppingCart = () => { // 加入购物车
.forEach(item => {
shop_cart_list.value = shop_cart_list.value.concat(item);
});
// 购物车为空提示
if (!shop_cart_list.value.length) {
showToast('请选择物资');
return;
}
// 校验购物车值
let error_list = shop_cart_list.value.filter((item) => { if (item.num === null || item.num === '') { return item;} })
if (error_list.length) {
......@@ -213,7 +217,7 @@ const goShoppingCart = () => { // 跳转购物车
}
const show_choose_material = ref(false);
const onCloseChoose = () => {
const onCloseChoose = () => { // 关闭选择物资弹窗回调
show_choose_material.value = false;
}
......