feat(shop): 重构店铺列表页面,支持按模式分类筛选
- 新增模式映射常量文件 - 扩展店铺列表接口参数类型 - 重构店铺列表页面布局为左右结构 - 添加模式分类导航功能 - 优化店铺列表筛选逻辑
This commit is contained in:
parent
48ece1eeae
commit
fa46750951
|
|
@ -2,6 +2,7 @@ import { http } from "@/http/http";
|
||||||
import type {
|
import type {
|
||||||
GetBalanceResponse,
|
GetBalanceResponse,
|
||||||
GetOrdersByOpenIdDTO,
|
GetOrdersByOpenIdDTO,
|
||||||
|
GetShopListParams,
|
||||||
OpenCabinetApiData,
|
OpenCabinetApiData,
|
||||||
QyLoginDTO,
|
QyLoginDTO,
|
||||||
QyLoginRequestParams,
|
QyLoginRequestParams,
|
||||||
|
|
@ -70,16 +71,15 @@ export async function getUserBalance(corpid: string, ab98UserId: number) {
|
||||||
return await http.get<GetBalanceResponse>("payment/getUserBalance", { corpid, ab98UserId });
|
return await http.get<GetBalanceResponse>("payment/getUserBalance", { corpid, ab98UserId });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getShopListApi(corpid: string, mode?: number) {
|
export async function getShopListApi(params: GetShopListParams) {
|
||||||
const params: any = {
|
|
||||||
corpid
|
|
||||||
};
|
|
||||||
if (typeof mode !== 'undefined') {
|
|
||||||
params.mode = mode;
|
|
||||||
}
|
|
||||||
return await http.get<ShopEntity[]>("shop/list", params);
|
return await http.get<ShopEntity[]>("shop/list", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCorpidById(cid?: number) {
|
export async function getCorpidById(cid?: number) {
|
||||||
return await http.get<string>("qy/getCorpidById", { id: cid ? cid : 0 });
|
return await http.get<string>("qy/getCorpidById", { id: cid ? cid : 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取模式列表 */
|
||||||
|
export function getModeListApi() {
|
||||||
|
return http.get<number[]>("shop/mode/list")
|
||||||
|
}
|
||||||
|
|
@ -254,3 +254,14 @@ export interface SearchGoodsDO extends ShopGoodsEntity {
|
||||||
/** 已分配库存 */
|
/** 已分配库存 */
|
||||||
totalStock?: number;
|
totalStock?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GetShopListParams {
|
||||||
|
/** 企业微信id */
|
||||||
|
corpid: string;
|
||||||
|
/** 不包含的运行模式 */
|
||||||
|
mode?: number;
|
||||||
|
/** 只查询该运行模式(0-支付模式 1-审批模式 2-借还模式 3-会员模式 4-耗材模式 5-暂存模式) */
|
||||||
|
eqMode?: number;
|
||||||
|
/** 运行模式列表(逗号分隔) */
|
||||||
|
modeList?: string;
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,8 @@ import { useAb98UserStore } from '@/pinia/stores/ab98-user'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useWxParamsStore } from '@/pinia/stores/wx-params'
|
import { useWxParamsStore } from '@/pinia/stores/wx-params'
|
||||||
import { useStorageCabinetStore } from '@/pinia/stores/storageCabinet'
|
import { useStorageCabinetStore } from '@/pinia/stores/storageCabinet'
|
||||||
|
import { getModeListApi } from '@/api/shop'
|
||||||
|
import { MODE_MAP } from '@/utils/maps/mode'
|
||||||
|
|
||||||
definePage({
|
definePage({
|
||||||
style: {
|
style: {
|
||||||
|
|
@ -36,24 +38,35 @@ const showShopList = ref<boolean>(true)
|
||||||
const shopList = ref<ShopEntity[]>([])
|
const shopList = ref<ShopEntity[]>([])
|
||||||
const shopId = ref<number>(0)
|
const shopId = ref<number>(0)
|
||||||
|
|
||||||
// tabs状态
|
// mode分类状态
|
||||||
const activeTab = ref<number>(0)
|
const modeList = ref<number[]>([])
|
||||||
const tabs = [
|
const activeModeCategory = ref<number>(0)
|
||||||
{ title: '借还柜', value: 0 },
|
|
||||||
{ title: '暂存柜', value: 1 }
|
|
||||||
]
|
|
||||||
|
|
||||||
// 根据activeTab过滤店铺列表
|
// 根据activeTab过滤店铺列表
|
||||||
|
// const filteredShopList = computed(() => {
|
||||||
|
// if (!shopList.value.length) return []
|
||||||
|
// if (activeTab.value === 0) {
|
||||||
|
// // 借还柜:显示mode不为5的shop
|
||||||
|
// return shopList.value.filter(shop => shop.mode !== 5)
|
||||||
|
// } else {
|
||||||
|
// // 暂存柜:显示mode为5的shop
|
||||||
|
// return shopList.value.filter(shop => shop.mode === 5)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 分类模式列表(包含"全部")
|
||||||
|
const categoryModes = computed(() => ['全部', ...modeList.value])
|
||||||
|
|
||||||
|
// 根据选中的mode分类过滤店铺列表
|
||||||
const filteredShopList = computed(() => {
|
const filteredShopList = computed(() => {
|
||||||
if (!shopList.value.length) return []
|
if (!shopList.value.length) return []
|
||||||
|
// 如果选中了"全部"或没有模式列表,返回所有店铺
|
||||||
if (activeTab.value === 0) {
|
if (activeModeCategory.value === 0 || !modeList.value.length) {
|
||||||
// 借还柜:显示mode不为5的shop
|
return shopList.value
|
||||||
return shopList.value.filter(shop => shop.mode !== 5)
|
|
||||||
} else {
|
|
||||||
// 暂存柜:显示mode为5的shop
|
|
||||||
return shopList.value.filter(shop => shop.mode === 5)
|
|
||||||
}
|
}
|
||||||
|
// 根据选中的mode过滤
|
||||||
|
const selectedMode = modeList.value[activeModeCategory.value - 1]
|
||||||
|
return shopList.value.filter(shop => shop.mode === selectedMode)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 计算当前选中的店铺模式
|
// 计算当前选中的店铺模式
|
||||||
|
|
@ -74,6 +87,33 @@ const isStorageMode = computed(() => selectedShopMode.value === 5)
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 点击mode分类导航
|
||||||
|
function handleModeCategoryClick(index: number) {
|
||||||
|
activeModeCategory.value = index
|
||||||
|
// 重新获取店铺列表
|
||||||
|
fetchShopListByMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据选中的mode分类获取店铺列表
|
||||||
|
async function fetchShopListByMode() {
|
||||||
|
try {
|
||||||
|
await wxStore.waitForHandleWxCallbackComplete()
|
||||||
|
const eqMode = activeModeCategory.value === 0
|
||||||
|
? undefined
|
||||||
|
: modeList.value[activeModeCategory.value - 1]
|
||||||
|
const res = await getShopListApi({ corpid: wxStore.corpid || '', eqMode })
|
||||||
|
console.log('获取店铺列表:', res)
|
||||||
|
if (res?.code === 0 && res?.data?.length > 0) {
|
||||||
|
shopList.value = res.data
|
||||||
|
} else {
|
||||||
|
shopList.value = []
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取店铺列表失败:', error)
|
||||||
|
shopList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 点击分类导航
|
// 点击分类导航
|
||||||
function handleShopSelect(selectedShopId: number) {
|
function handleShopSelect(selectedShopId: number) {
|
||||||
shopId.value = selectedShopId
|
shopId.value = selectedShopId
|
||||||
|
|
@ -187,61 +227,77 @@ onLoad(async (query) => {
|
||||||
console.error('用户登录处理失败:', error);
|
console.error('用户登录处理失败:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取店铺列表
|
// 获取mode列表
|
||||||
if (showShopList.value) {
|
|
||||||
try {
|
try {
|
||||||
await wxStore.waitForHandleWxCallbackComplete();
|
const modeRes = await getModeListApi();
|
||||||
const res = await getShopListApi(wxStore.corpid || '');
|
if (modeRes?.code === 0 && modeRes?.data?.length > 0) {
|
||||||
console.log('获取店铺列表:', res);
|
modeList.value = modeRes.data;
|
||||||
if (res?.code === 0 && res?.data?.length > 0) {
|
|
||||||
shopList.value = res.data;
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取店铺列表失败:', error);
|
console.error('获取mode列表失败:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取店铺列表
|
||||||
|
if (showShopList.value) {
|
||||||
|
await fetchShopListByMode();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
// 获取店铺列表
|
// 获取店铺列表
|
||||||
if (showShopList.value) {
|
if (showShopList.value) {
|
||||||
|
// 如果mode列表还没获取,先获取
|
||||||
|
if (modeList.value.length === 0) {
|
||||||
try {
|
try {
|
||||||
await wxStore.waitForHandleWxCallbackComplete();
|
const modeRes = await getModeListApi();
|
||||||
const res = await getShopListApi(wxStore.corpid || '');
|
if (modeRes?.code === 0 && modeRes?.data?.length > 0) {
|
||||||
console.log('获取店铺列表:', res);
|
modeList.value = modeRes.data;
|
||||||
if (res?.code === 0 && res?.data?.length > 0) {
|
|
||||||
shopList.value = res.data;
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取店铺列表失败:', error);
|
console.error('获取mode列表失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await fetchShopListByMode();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 直接使用 shop-list 类,合并 shop-container 的样式 -->
|
<!-- 容器使用左右布局 -->
|
||||||
<view class="shop-list">
|
<view :class="['container', { 'container-full': !showShopList }]">
|
||||||
<view class="shop-header">
|
<!-- 页面顶部header -->
|
||||||
|
<view v-if="showShopList" class="page-header">
|
||||||
<wd-img
|
<wd-img
|
||||||
:src="`/static/cover.jpg`"
|
:src="`/static/cover.jpg`"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="150"
|
height="120"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
></wd-img>
|
></wd-img>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 店铺选择列表内容 -->
|
<!-- 左右布局区域 -->
|
||||||
<view v-if="showShopList" class="shop-list-content">
|
<view v-if="showShopList" class="content-wrapper">
|
||||||
<!-- tabs切换 -->
|
<!-- 左侧分类导航 -->
|
||||||
<wd-tabs v-model="activeTab" class="shop-tabs">
|
<view class="left-nav">
|
||||||
<wd-tab v-for="tab in tabs" :key="tab.value" :title="tab.title" :name="tab.value"></wd-tab>
|
<!-- <view class="back-btn" @click="backToShopList">
|
||||||
</wd-tabs>
|
<wd-icon name="arrow-left" size="16px"></wd-icon>
|
||||||
|
<text>选择机柜</text>
|
||||||
<!-- <view class="shop-prompt">
|
|
||||||
<view class="prompt-text">请选择机柜地址:</view>
|
|
||||||
</view> -->
|
</view> -->
|
||||||
|
<scroll-view class="category-nav" scroll-y>
|
||||||
|
<view
|
||||||
|
v-for="(mode, index) in categoryModes"
|
||||||
|
:key="index"
|
||||||
|
:class="['category-item', { active: activeModeCategory === index }]"
|
||||||
|
@click="handleModeCategoryClick(index)"
|
||||||
|
>
|
||||||
|
{{ mode === '全部' ? '全部' : (MODE_MAP[mode] || `模式${mode}`) }}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 右侧店铺列表 -->
|
||||||
|
<view class="shop-list">
|
||||||
|
<view class="shop-list-content">
|
||||||
<view class="shop-row">
|
<view class="shop-row">
|
||||||
<template v-if="filteredShopList.length > 0">
|
<template v-if="filteredShopList.length > 0">
|
||||||
<view v-for="shop in filteredShopList" :key="shop.shopId" class="shop-col" @click="handleShopSelect(shop.shopId)">
|
<view v-for="shop in filteredShopList" :key="shop.shopId" class="shop-col" @click="handleShopSelect(shop.shopId)">
|
||||||
|
|
@ -269,6 +325,8 @@ onShow(async () => {
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 租用格口列表 -->
|
<!-- 租用格口列表 -->
|
||||||
<RentingCabinetContainer
|
<RentingCabinetContainer
|
||||||
|
|
@ -296,61 +354,100 @@ onShow(async () => {
|
||||||
@checkout="handleCheckout"
|
@checkout="handleCheckout"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<wd-gap safe-area-bottom height="20"></wd-gap>
|
<!-- <wd-gap safe-area-bottom height="20"></wd-gap> -->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.shop-list {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
// height: calc(100vh - 94px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: #f7f8fa;
|
background: #f7f8fa;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.container-full {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
width: 100%;
|
||||||
|
height: 120px;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-nav {
|
||||||
|
width: 100px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #fff;
|
||||||
|
border-right: 1px solid #e0e0e0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 8px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
text {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-nav {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-item {
|
||||||
|
padding: 16px 8px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #f7f8fa;
|
||||||
|
color: #F56C6C;
|
||||||
|
border-left-color: #F56C6C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-list {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.shop-list-content {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.shop-header {
|
.shop-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
height: 120px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shop-list-content {
|
|
||||||
flex: 1;
|
|
||||||
height: calc(100vh - 150px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shop-tabs {
|
|
||||||
margin: 8px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shop-prompt {
|
|
||||||
margin: 8px;
|
|
||||||
padding: 12px 16px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
.prompt-text {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.shop-row {
|
.shop-row {
|
||||||
overflow-y: auto;
|
padding: 10px;
|
||||||
overflow-x: hidden;
|
|
||||||
padding: 10px 8px 0 8px;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
flex: 1;
|
|
||||||
height: calc(100vh - 150px - 52px);
|
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -369,8 +466,8 @@ onShow(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.shop-col {
|
.shop-col {
|
||||||
width: calc(50% - 4px);
|
width: 100%;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shop-item {
|
.shop-item {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const MODE_MAP: Record<number, string> = {
|
||||||
|
0: '支付柜',
|
||||||
|
1: '审批柜',
|
||||||
|
2: '借还柜',
|
||||||
|
3: '会员柜',
|
||||||
|
4: '耗材柜',
|
||||||
|
5: '暂存柜',
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue