|
@@ -0,0 +1,496 @@
|
|
|
+<template>
|
|
|
+ <u-popup
|
|
|
+ :show="show"
|
|
|
+ mode="bottom"
|
|
|
+ @close="handleClose"
|
|
|
+ :closeOnClickOverlay="false"
|
|
|
+ closeable
|
|
|
+ :safeAreaInsetBottom="true"
|
|
|
+ :round="20"
|
|
|
+ >
|
|
|
+ <view class="filter-popup">
|
|
|
+ <view class="filter-header">
|
|
|
+ <u-tabs
|
|
|
+ :list="tabList"
|
|
|
+ :current="currentTab"
|
|
|
+ @change="tabChange"
|
|
|
+ :activeStyle="{
|
|
|
+ color: '#4080FF',
|
|
|
+ fontWeight: 'bold',
|
|
|
+ }"
|
|
|
+ :inactiveStyle="{
|
|
|
+ color: '#333333',
|
|
|
+ }"
|
|
|
+ itemStyle="padding-left: 30rpx; padding-right: 30rpx; height: 100rpx;"
|
|
|
+ ></u-tabs>
|
|
|
+ </view>
|
|
|
+ <view class="filter-content">
|
|
|
+ <!-- 货物选项 -->
|
|
|
+ <scroll-view scroll-y class="filter-scroll" v-if="currentTab === 0">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in goodsOptions"
|
|
|
+ :key="index"
|
|
|
+ class="filter-item"
|
|
|
+ :class="{ active: selectedValues.goods === item.value }"
|
|
|
+ @click="selectFilter('goods', item.value)"
|
|
|
+ >
|
|
|
+ <text>{{ item.label }}</text>
|
|
|
+ <u-icon
|
|
|
+ v-if="selectedValues.goods === item.value"
|
|
|
+ name="checkbox-mark"
|
|
|
+ color="#4080FF"
|
|
|
+ size="20"
|
|
|
+ ></u-icon>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 盘点人选项 -->
|
|
|
+ <scroll-view scroll-y class="filter-scroll" v-if="currentTab === 1">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in userOptions"
|
|
|
+ :key="index"
|
|
|
+ class="filter-item"
|
|
|
+ :class="{ active: selectedValues.user === item.value }"
|
|
|
+ @click="selectFilter('user', item.value)"
|
|
|
+ >
|
|
|
+ <text>{{ item.label }}</text>
|
|
|
+ <u-icon
|
|
|
+ v-if="selectedValues.user === item.value"
|
|
|
+ name="checkbox-mark"
|
|
|
+ color="#4080FF"
|
|
|
+ size="20"
|
|
|
+ ></u-icon>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <!-- 类目选项 - 左右布局实现二级联动 -->
|
|
|
+ <view class="category-container" v-if="currentTab === 2">
|
|
|
+ <view class="category-sidebar">
|
|
|
+ <scroll-view scroll-y style="height: 100%">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in categorySidebarList"
|
|
|
+ :key="index"
|
|
|
+ class="sidebar-item"
|
|
|
+ :class="{ active: currentCategoryIndex === index }"
|
|
|
+ @click="changeCategoryIndex(index)"
|
|
|
+ >
|
|
|
+ <text>{{ item.name }}</text>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ <view class="category-content">
|
|
|
+ <scroll-view scroll-y style="height: 100%">
|
|
|
+ <u-checkbox-group
|
|
|
+ v-model="selectedValues.category"
|
|
|
+ placement="column"
|
|
|
+ @change="onCategoryChange"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in categoryContentList"
|
|
|
+ :key="index"
|
|
|
+ class="checkbox-item"
|
|
|
+ >
|
|
|
+ <u-checkbox
|
|
|
+ :name="item.value"
|
|
|
+ shape="circle"
|
|
|
+ activeColor="#4080FF"
|
|
|
+ :label="item.label"
|
|
|
+ size="20"
|
|
|
+ >
|
|
|
+ </u-checkbox>
|
|
|
+ </view>
|
|
|
+ </u-checkbox-group>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 库位选项 - 左右布局实现二级联动 -->
|
|
|
+ <view class="category-container" v-if="currentTab === 3">
|
|
|
+ <view class="category-sidebar">
|
|
|
+ <scroll-view scroll-y style="height: 100%">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in locationSidebarList"
|
|
|
+ :key="index"
|
|
|
+ class="sidebar-item"
|
|
|
+ :class="{ active: currentLocationIndex === index }"
|
|
|
+ @click="changeLocationIndex(index)"
|
|
|
+ >
|
|
|
+ <text>{{ item.name }}</text>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ <view class="category-content">
|
|
|
+ <scroll-view scroll-y style="height: 100%">
|
|
|
+ <u-checkbox-group
|
|
|
+ v-model="selectedValues.location"
|
|
|
+ placement="column"
|
|
|
+ @change="onLocationChange"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in locationContentList"
|
|
|
+ :key="index"
|
|
|
+ class="checkbox-item"
|
|
|
+ >
|
|
|
+ <u-checkbox
|
|
|
+ :name="item.value"
|
|
|
+ shape="circle"
|
|
|
+ activeColor="#4080FF"
|
|
|
+ :label="item.label"
|
|
|
+ size="20"
|
|
|
+ >
|
|
|
+ </u-checkbox>
|
|
|
+ </view>
|
|
|
+ </u-checkbox-group>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="filter-footer">
|
|
|
+ <u-button
|
|
|
+ text="重置"
|
|
|
+ :plain="true"
|
|
|
+ shape="circle"
|
|
|
+ @click="resetFilter"
|
|
|
+ class="footer-btn"
|
|
|
+ ></u-button>
|
|
|
+ <u-button
|
|
|
+ text="确定"
|
|
|
+ type="primary"
|
|
|
+ shape="circle"
|
|
|
+ @click="confirmFilter"
|
|
|
+ class="footer-btn"
|
|
|
+ ></u-button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: "InventoryFilterPopup",
|
|
|
+ props: {
|
|
|
+ show: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 初始选中值
|
|
|
+ defaultValues: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({
|
|
|
+ goods: "",
|
|
|
+ user: "",
|
|
|
+ category: [],
|
|
|
+ location: [],
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ currentTab: 0,
|
|
|
+ tabList: [
|
|
|
+ { name: "未盘" },
|
|
|
+ { name: "盘点人" },
|
|
|
+ { name: "类目" },
|
|
|
+ { name: "库位" },
|
|
|
+ ],
|
|
|
+ // 货物选项
|
|
|
+ goodsOptions: [
|
|
|
+ { label: "全部", value: "" },
|
|
|
+ { label: "未盘", value: "unchecked" },
|
|
|
+ { label: "盘盈", value: "overflow" },
|
|
|
+ { label: "盘亏", value: "loss" },
|
|
|
+ { label: "无差异", value: "normal" },
|
|
|
+ ],
|
|
|
+ // 盘点人选项
|
|
|
+ userOptions: [
|
|
|
+ { label: "全部", value: "" },
|
|
|
+ { label: "刘双秀", value: "刘双秀" },
|
|
|
+ ],
|
|
|
+ // 类目树形数据
|
|
|
+ categoryTree: [
|
|
|
+ {
|
|
|
+ id: "all",
|
|
|
+ name: "全部",
|
|
|
+ children: [
|
|
|
+ { label: "生活用品", value: "daily" },
|
|
|
+ { label: "厨房餐具", value: "kitchen" },
|
|
|
+ { label: "个人洗护", value: "personal" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "summer",
|
|
|
+ name: "夏季热卖",
|
|
|
+ children: [
|
|
|
+ { label: "防晒", value: "summer_sunscreen" },
|
|
|
+ { label: "泳衣", value: "summer_swimwear" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "disposable",
|
|
|
+ name: "一次用品",
|
|
|
+ children: [
|
|
|
+ { label: "餐具", value: "disposable_tableware" },
|
|
|
+ { label: "纸巾", value: "disposable_tissue" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "swimming",
|
|
|
+ name: "游泳运动",
|
|
|
+ children: [
|
|
|
+ { label: "泳镜", value: "swimming_goggles" },
|
|
|
+ { label: "泳帽", value: "swimming_caps" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "cleaning",
|
|
|
+ name: "家庭清洁",
|
|
|
+ children: [
|
|
|
+ { label: "洗衣液", value: "cleaning_detergent" },
|
|
|
+ { label: "清洁剂", value: "cleaning_agent" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ // 当前选中的类目侧边栏索引
|
|
|
+ currentCategoryIndex: 0,
|
|
|
+
|
|
|
+ // 库位树形数据
|
|
|
+ locationTree: [
|
|
|
+ {
|
|
|
+ id: "all",
|
|
|
+ name: "全部",
|
|
|
+ children: [],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "zone_a",
|
|
|
+ name: "A区",
|
|
|
+ children: [
|
|
|
+ { label: "A1-1-1", value: "A1-1-1" },
|
|
|
+ { label: "A1-1-2", value: "A1-1-2" },
|
|
|
+ { label: "A1-2-1", value: "A1-2-1" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "zone_b",
|
|
|
+ name: "B区",
|
|
|
+ children: [
|
|
|
+ { label: "B2-1-1", value: "B2-1-1" },
|
|
|
+ { label: "B2-1-2", value: "B2-1-2" },
|
|
|
+ { label: "B2-2-1", value: "B2-2-1" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: "zone_c",
|
|
|
+ name: "C区",
|
|
|
+ children: [
|
|
|
+ { label: "C6-2-2", value: "C6-2-2" },
|
|
|
+ { label: "C6-3-1", value: "C6-3-1" },
|
|
|
+ { label: "C6-3-2", value: "C6-3-2" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ // 当前选中的库位侧边栏索引
|
|
|
+ currentLocationIndex: 0,
|
|
|
+
|
|
|
+ // 选中的筛选值
|
|
|
+ selectedValues: {
|
|
|
+ goods: "",
|
|
|
+ user: "",
|
|
|
+ category: [],
|
|
|
+ location: [],
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 类目侧边栏列表
|
|
|
+ categorySidebarList() {
|
|
|
+ return this.categoryTree.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ id: item.id,
|
|
|
+ }));
|
|
|
+ },
|
|
|
+ // 当前显示的类目内容
|
|
|
+ categoryContentList() {
|
|
|
+ return this.categoryTree[this.currentCategoryIndex]?.children || [];
|
|
|
+ },
|
|
|
+ // 库位侧边栏列表
|
|
|
+ locationSidebarList() {
|
|
|
+ return this.locationTree.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ id: item.id,
|
|
|
+ }));
|
|
|
+ },
|
|
|
+ // 当前显示的库位内容
|
|
|
+ locationContentList() {
|
|
|
+ return this.locationTree[this.currentLocationIndex]?.children || [];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ // 初始化选中值
|
|
|
+ this.selectedValues = {
|
|
|
+ goods: this.defaultValues.goods || "",
|
|
|
+ user: this.defaultValues.user || "",
|
|
|
+ category: this.defaultValues.category || [],
|
|
|
+ location: this.defaultValues.location || [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 标签切换
|
|
|
+ tabChange({ index }) {
|
|
|
+ this.currentTab = index;
|
|
|
+ },
|
|
|
+ // 选择筛选项(单选)
|
|
|
+ selectFilter(type, value) {
|
|
|
+ this.selectedValues[type] = value;
|
|
|
+ },
|
|
|
+ // 切换类目侧边栏
|
|
|
+ changeCategoryIndex(index) {
|
|
|
+ // 如果切换了侧边栏,则重置该类别下的选择状态
|
|
|
+ if (this.currentCategoryIndex !== index) {
|
|
|
+ this.currentCategoryIndex = index;
|
|
|
+ // 重置当前类别的选择状态
|
|
|
+ this.selectedValues.category = [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 切换库位侧边栏
|
|
|
+ changeLocationIndex(index) {
|
|
|
+ // 如果切换了侧边栏,则重置该类别下的选择状态
|
|
|
+ if (this.currentLocationIndex !== index) {
|
|
|
+ this.currentLocationIndex = index;
|
|
|
+ // 重置当前库位的选择状态
|
|
|
+ this.selectedValues.location = [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 重置筛选
|
|
|
+ resetFilter() {
|
|
|
+ this.selectedValues = {
|
|
|
+ goods: "",
|
|
|
+ user: "",
|
|
|
+ category: [],
|
|
|
+ location: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ // 确认筛选
|
|
|
+ confirmFilter() {
|
|
|
+ this.$emit("confirm", { ...this.selectedValues });
|
|
|
+ this.handleClose();
|
|
|
+ },
|
|
|
+ // 关闭弹窗
|
|
|
+ handleClose() {
|
|
|
+ this.$emit("update:show", false);
|
|
|
+ this.$emit("close");
|
|
|
+ },
|
|
|
+ // 处理类目选择变化
|
|
|
+ onCategoryChange(value) {
|
|
|
+ this.selectedValues.category = value;
|
|
|
+ },
|
|
|
+ // 处理库位选择变化
|
|
|
+ onLocationChange(value) {
|
|
|
+ this.selectedValues.location = value;
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.filter-popup {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 70vh;
|
|
|
+
|
|
|
+ .filter-header {
|
|
|
+ border-bottom: 1rpx solid #f5f6f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-content {
|
|
|
+ flex: 1;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .filter-scroll {
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 30rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ border-bottom: 1rpx solid #f5f6f7;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background-color: #f0f6fb;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 类目和库位二级联动样式
|
|
|
+ .category-container {
|
|
|
+ display: flex;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .category-sidebar {
|
|
|
+ width: 200rpx;
|
|
|
+ height: 100%;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+
|
|
|
+ .sidebar-item {
|
|
|
+ padding: 30rpx 20rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background-color: #ffffff;
|
|
|
+ color: #4080ff;
|
|
|
+ position: relative;
|
|
|
+ font-weight: 500;
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 30%;
|
|
|
+ height: 40%;
|
|
|
+ width: 6rpx;
|
|
|
+ background-color: #4080ff;
|
|
|
+ border-radius: 3rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-content {
|
|
|
+ flex: 1;
|
|
|
+ height: 100%;
|
|
|
+ background-color: #ffffff;
|
|
|
+ padding: 0 30rpx;
|
|
|
+
|
|
|
+ .checkbox-item {
|
|
|
+ padding: 30rpx 0;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border-bottom: 1rpx solid #f5f6f7;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-footer {
|
|
|
+ display: flex;
|
|
|
+ padding: 30rpx;
|
|
|
+ border-top: 1rpx solid #f5f6f7;
|
|
|
+
|
|
|
+ .footer-btn {
|
|
|
+ flex: 1;
|
|
|
+ margin: 0 16rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|