feat(rental): 新增我的柜子页面及相关功能
- 添加我的柜子页面路由和导航入口 - 实现用户租赁柜子列表展示功能 - 优化订单列表样式和商品信息展示 - 在用户信息中增加ab98User字段支持 - 统一订单获取接口参数格式
This commit is contained in:
parent
7ab5130cff
commit
32f90300c8
|
@ -163,6 +163,7 @@ export interface GetBalanceResponse {
|
||||||
useBalance: number
|
useBalance: number
|
||||||
/** 借呗总额 */
|
/** 借呗总额 */
|
||||||
balanceLimit: number
|
balanceLimit: number
|
||||||
|
ab98User: ab98UserDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QyLoginDTO {
|
export interface QyLoginDTO {
|
||||||
|
|
|
@ -126,7 +126,7 @@ const handleSubmit = async () => {
|
||||||
const { code, data } = await submitApprovalApi(formData.value)
|
const { code, data } = await submitApprovalApi(formData.value)
|
||||||
|
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
orderStore.getOrders(wxStore.corpid, wxStore.openid, wxStore.qyUserId);
|
orderStore.getOrders(wxStore.corpid, wxStore.openid, wxStore.qyUserId, 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await showConfirmDialog({
|
await showConfirmDialog({
|
||||||
|
|
|
@ -90,6 +90,12 @@ wxStore.refreshBalance();
|
||||||
<span>订单列表</span>
|
<span>订单列表</span>
|
||||||
</div>
|
</div>
|
||||||
</van-col>
|
</van-col>
|
||||||
|
<van-col span="8">
|
||||||
|
<div class="custom-btn" @click="router.push('/rental-list')">
|
||||||
|
<van-icon name="orders-o" size="20px" />
|
||||||
|
<span>我的柜子</span>
|
||||||
|
</div>
|
||||||
|
</van-col>
|
||||||
<!-- <van-col span="6">
|
<!-- <van-col span="6">
|
||||||
<div v-if="wxStore.isCabinetAdmin" class="custom-btn" @click="router.push('/manage/goods')">
|
<div v-if="wxStore.isCabinetAdmin" class="custom-btn" @click="router.push('/manage/goods')">
|
||||||
<van-icon name="comment-o" size="20px" />
|
<van-icon name="comment-o" size="20px" />
|
||||||
|
@ -115,7 +121,6 @@ wxStore.refreshBalance();
|
||||||
</div>
|
</div>
|
||||||
</van-col>
|
</van-col>
|
||||||
<van-col span="8"></van-col>
|
<van-col span="8"></van-col>
|
||||||
<van-col span="8"></van-col>
|
|
||||||
</van-row>
|
</van-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -50,7 +50,7 @@ function backToHome() {
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => orderId.value, async (newVal) => {
|
watch(() => orderId.value, async (newVal) => {
|
||||||
await orderStore.getOrders(wxStore.corpid, wxStore.openid, wxStore.qyUserId)
|
await orderStore.getOrders(wxStore.corpid, wxStore.openid, wxStore.qyUserId, 0)
|
||||||
currentOrder.value = orderStore.orders.find(o => o.orderId === newVal)
|
currentOrder.value = orderStore.orders.find(o => o.orderId === newVal)
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -41,7 +41,7 @@ const getStatusText = (status: number) => {
|
||||||
<template>
|
<template>
|
||||||
<div class="order-list">
|
<div class="order-list">
|
||||||
<!-- 状态切换标签页 -->
|
<!-- 状态切换标签页 -->
|
||||||
<van-tabs v-model:active="activeTab" @change="handleTabChange">
|
<van-tabs v-model:active="activeTab" @change="handleTabChange" style="margin-bottom: 8px;">
|
||||||
<van-tab title="未退还"></van-tab>
|
<van-tab title="未退还"></van-tab>
|
||||||
<van-tab title="已退还"></van-tab>
|
<van-tab title="已退还"></van-tab>
|
||||||
</van-tabs>
|
</van-tabs>
|
||||||
|
@ -72,7 +72,7 @@ const getStatusText = (status: number) => {
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<van-image
|
<van-image
|
||||||
:src="goods.goodsInfo.coverImg"
|
:src="goods.goodsInfo?.coverImg"
|
||||||
width="80"
|
width="80"
|
||||||
height="80"
|
height="80"
|
||||||
class="product-image"
|
class="product-image"
|
||||||
|
@ -80,7 +80,7 @@ const getStatusText = (status: number) => {
|
||||||
</template>
|
</template>
|
||||||
<div class="product-info">
|
<div class="product-info">
|
||||||
<div class="product-name van-ellipsis">
|
<div class="product-name van-ellipsis">
|
||||||
{{ goods.goodsInfo.goodsName }}
|
{{ goods.goodsInfo?.goodsName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="product-meta">
|
<div class="product-meta">
|
||||||
<span class="status">状态: {{ getStatusText(order.status) }}</span>
|
<span class="status">状态: {{ getStatusText(order.status) }}</span>
|
||||||
|
@ -109,7 +109,7 @@ const getStatusText = (status: number) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-item {
|
.order-item {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 8px;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -118,7 +118,7 @@ const getStatusText = (status: number) => {
|
||||||
.order-header {
|
.order-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 10px 15px;
|
padding: 10px 15px 5px 15px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,6 @@ const getStatusText = (status: number) => {
|
||||||
.goods-item {
|
.goods-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
border-bottom: 1px solid #f5f5f5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goods-item:last-child {
|
goods-item:last-child {
|
||||||
|
|
|
@ -97,7 +97,6 @@ async function handleOpenCabinet(item: OrderGoods) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="order-detail" v-if="order">
|
<div class="order-detail" v-if="order">
|
||||||
<h2>订单详情</h2>
|
|
||||||
|
|
||||||
<div class="order-info">
|
<div class="order-info">
|
||||||
<p>订单号: {{ order.orderId }}</p>
|
<p>订单号: {{ order.orderId }}</p>
|
||||||
|
|
|
@ -1,24 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="showShopList" class="shop-list">
|
<div class="cabinet-container van-safe-area-bottom">
|
||||||
<div class="shop-prompt">
|
|
||||||
<van-cell title="请选择机柜地址:" center />
|
|
||||||
</div>
|
|
||||||
<van-row :gutter="[10, 10]" class="shop-row" justify="start">
|
|
||||||
<van-col v-for="shop in shopList" :key="shop.shopId" span="12" class="shop-col">
|
|
||||||
<div class="shop-item" @click="handleShopSelect(shop.shopId)">
|
|
||||||
<van-image :src="shop.coverImg || `${publicPath}product-image.png`" class="shop-cover-img" fit="cover" />
|
|
||||||
<div class="shop-info">
|
|
||||||
<van-icon name="shop-o" size="20" class="shop-icon" />
|
|
||||||
<div class="shop-name van-ellipsis">{{ shop.shopName }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</van-col>
|
|
||||||
<van-col v-if="shopList.length % 2 === 0" span="12" class="shop-col"></van-col>
|
|
||||||
</van-row>
|
|
||||||
</div>
|
|
||||||
<div v-else class="cabinet-container van-safe-area-bottom">
|
|
||||||
<div class="left-container">
|
<div class="left-container">
|
||||||
<van-button icon="revoke" type="default" class="showShopListBtn" @click="handleBackToShopList">重选地址</van-button>
|
|
||||||
<van-sidebar v-model="activeCabinet" class="cabinet-sidebar" @change="onCabinetChange">
|
<van-sidebar v-model="activeCabinet" class="cabinet-sidebar" @change="onCabinetChange">
|
||||||
<van-sidebar-item v-for="cabinet in cabinetList" :key="cabinet.cabinetId" :title="cabinet.cabinetName" />
|
<van-sidebar-item v-for="cabinet in cabinetList" :key="cabinet.cabinetId" :title="cabinet.cabinetName" />
|
||||||
</van-sidebar>
|
</van-sidebar>
|
||||||
|
@ -37,25 +19,18 @@
|
||||||
</template>
|
</template>
|
||||||
<div class="product-info">
|
<div class="product-info">
|
||||||
<div class="goods-info">
|
<div class="goods-info">
|
||||||
<div v-if="locker.goodsName">
|
<div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="locker-number">格口 {{ locker.cellNo }}</div>
|
<div class="locker-number">格口 {{ locker.cellNo }}</div>
|
||||||
<div class="goods-price">¥{{ (locker.price || 0).toFixed(2) }}</div>
|
<div class="goods-price">¥{{ (locker.price || 0).toFixed(2) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="goods-name">{{ locker.goodsName }}</div>
|
<div class="goods-name"></div>
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<div class="info-row">
|
|
||||||
<div class="locker-number">格口 {{ locker.cellNo }}</div>
|
|
||||||
<div class="goods-price">¥0.00</div>
|
|
||||||
</div>
|
|
||||||
<div class="goods-name">空闲</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<van-button size="small" plain hairline :loading="openingLockerId === locker.lockerId"
|
<van-button size="small" plain hairline :loading="openingLockerId === locker.lockerId"
|
||||||
@click="handleOpenLocker(locker)">
|
@click="handleOpenLocker(locker)">
|
||||||
立即开启
|
开启格口
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -74,9 +49,10 @@ import type { RentingCabinetDetailDTO, CabinetCellEntity } from '@/common/apis/c
|
||||||
import { useWxStore } from '@/pinia/stores/wx';
|
import { useWxStore } from '@/pinia/stores/wx';
|
||||||
import { publicPath } from "@/common/utils/path";
|
import { publicPath } from "@/common/utils/path";
|
||||||
import { showDialog, showToast } from 'vant';
|
import { showDialog, showToast } from 'vant';
|
||||||
|
import { useAb98UserStore } from '@/pinia/stores/ab98-user';
|
||||||
|
|
||||||
const wxStore = useWxStore();
|
const wxStore = useWxStore();
|
||||||
const { userid: qyUserid, name: qyName, corpid } = storeToRefs(wxStore);
|
const { userid: userid, qyUserId: qyUserId, name: qyName, corpid, ab98User } = storeToRefs(wxStore);
|
||||||
|
|
||||||
const activeCabinet = ref(0)
|
const activeCabinet = ref(0)
|
||||||
const cabinetList = ref<CabinetItem[]>([])
|
const cabinetList = ref<CabinetItem[]>([])
|
||||||
|
@ -85,11 +61,6 @@ const openingLockerId = ref<number | null>(null)
|
||||||
const showBindGoodsPopup = ref(false)
|
const showBindGoodsPopup = ref(false)
|
||||||
const currentLocker = ref<LockerItem | null>(null)
|
const currentLocker = ref<LockerItem | null>(null)
|
||||||
const cabinetData = ref<RentingCabinetDetailDTO[]>([]);
|
const cabinetData = ref<RentingCabinetDetailDTO[]>([]);
|
||||||
// 机柜地址选择相关状态
|
|
||||||
const showShopList = ref(true);
|
|
||||||
const shopList = ref<ShopEntity[]>([]);
|
|
||||||
const shopId = ref<number>(0);
|
|
||||||
const selectedShop = ref<ShopEntity | null>(null);
|
|
||||||
let scrollListener: any[] = [];
|
let scrollListener: any[] = [];
|
||||||
|
|
||||||
interface CabinetItem {
|
interface CabinetItem {
|
||||||
|
@ -111,11 +82,12 @@ interface LockerItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户租用的机柜列表
|
// 获取用户租用的机柜列表
|
||||||
const loadUserRentedCabinetDetail = async (selectedShopId?: number) => {
|
const loadUserRentedCabinetDetail = async () => {
|
||||||
const targetShopId = selectedShopId || shopId.value;
|
if (!ab98User.value || !ab98User.value.ab98UserId) {
|
||||||
if (!targetShopId || !corpid.value || !qyUserid.value) return;
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const { data } = await getUserRentedCabinetListApi(corpid.value, Number(qyUserid.value));
|
const { data } = await getUserRentedCabinetListApi(corpid.value, ab98User.value.ab98UserId);
|
||||||
cabinetData.value = data || [];
|
cabinetData.value = data || [];
|
||||||
cabinetList.value = cabinetData.value.map(cabinet => ({
|
cabinetList.value = cabinetData.value.map(cabinet => ({
|
||||||
cabinetId: cabinet.cabinetId,
|
cabinetId: cabinet.cabinetId,
|
||||||
|
@ -142,7 +114,7 @@ const updateLockerList = (cabinet: RentingCabinetDetailDTO) => {
|
||||||
status: cell.isRented ? 1 : 0,
|
status: cell.isRented ? 1 : 0,
|
||||||
statusClass: cell.isRented ? 'occupied' : 'available',
|
statusClass: cell.isRented ? 'occupied' : 'available',
|
||||||
// 这里假设商品信息可能在其他字段中,根据实际情况调整
|
// 这里假设商品信息可能在其他字段中,根据实际情况调整
|
||||||
goodsName: '已租用商品',
|
goodsName: '',
|
||||||
price: cell.cellPrice,
|
price: cell.cellPrice,
|
||||||
coverImg: `${publicPath}img/product-image.svg`
|
coverImg: `${publicPath}img/product-image.svg`
|
||||||
}))
|
}))
|
||||||
|
@ -162,7 +134,7 @@ const handleOpenLocker = async (locker: LockerItem) => {
|
||||||
// 调用打开柜口接口
|
// 调用打开柜口接口
|
||||||
await openCabinet(cabinetList.value[activeCabinet.value].cabinetId, locker.lockerNumber, {
|
await openCabinet(cabinetList.value[activeCabinet.value].cabinetId, locker.lockerNumber, {
|
||||||
cellId: locker.lockerId,
|
cellId: locker.lockerId,
|
||||||
userid: qyUserid.value,
|
userid: userid.value,
|
||||||
isInternal: 2,
|
isInternal: 2,
|
||||||
name: qyName.value,
|
name: qyName.value,
|
||||||
mobile: '',
|
mobile: '',
|
||||||
|
@ -177,40 +149,7 @@ const handleOpenLocker = async (locker: LockerItem) => {
|
||||||
|
|
||||||
// 初始化方法
|
// 初始化方法
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
if (showShopList.value) {
|
|
||||||
await getShopList();
|
|
||||||
} else if (shopId.value) {
|
|
||||||
await loadUserRentedCabinetDetail();
|
await loadUserRentedCabinetDetail();
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取商店列表
|
|
||||||
const getShopList = async () => {
|
|
||||||
try {
|
|
||||||
const res = await getShopListApi(wxStore.corpid, -1);
|
|
||||||
if (res?.code === 0 && res?.data?.length > 0) {
|
|
||||||
shopList.value = res.data;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取商店列表失败:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 选择商店
|
|
||||||
const handleShopSelect = (selectedShopId: number) => {
|
|
||||||
const shop = shopList.value.find(s => s.shopId === selectedShopId);
|
|
||||||
if (shop) {
|
|
||||||
selectedShop.value = shop;
|
|
||||||
shopId.value = selectedShopId;
|
|
||||||
}
|
|
||||||
showShopList.value = false;
|
|
||||||
loadUserRentedCabinetDetail(selectedShopId);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 返回商店列表
|
|
||||||
const handleBackToShopList = () => {
|
|
||||||
showShopList.value = true;
|
|
||||||
shopId.value = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -120,6 +120,9 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
if (!userid.value) {
|
if (!userid.value) {
|
||||||
userid.value = balanceRes.data.userid;
|
userid.value = balanceRes.data.userid;
|
||||||
}
|
}
|
||||||
|
if (!ab98User.value && balanceRes.data.ab98User) {
|
||||||
|
setAb98User(balanceRes.data.ab98User);
|
||||||
|
}
|
||||||
/* if (!corpid.value) {
|
/* if (!corpid.value) {
|
||||||
corpid.value = balanceRes.data.corpid;
|
corpid.value = balanceRes.data.corpid;
|
||||||
} */
|
} */
|
||||||
|
|
|
@ -73,6 +73,27 @@ export const routes: RouteRecordRaw[] = [
|
||||||
component: () => import('@/pages/order/index.vue'),
|
component: () => import('@/pages/order/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '订单详情',
|
title: '订单详情',
|
||||||
|
layout: {
|
||||||
|
navBar: {
|
||||||
|
showNavBar: true,
|
||||||
|
showLeftArrow: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
requiresAuth: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/rental-list',
|
||||||
|
name: 'RentalList',
|
||||||
|
component: () => import('@/pages/rental/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '我的柜子',
|
||||||
|
layout: {
|
||||||
|
navBar: {
|
||||||
|
showNavBar: true,
|
||||||
|
showLeftArrow: true
|
||||||
|
}
|
||||||
|
},
|
||||||
requiresAuth: true
|
requiresAuth: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue