feat(router): 恢复管理员路由守卫检查
feat(api): 为余额查询接口添加corpid参数 refactor(product): 优化商品获取逻辑并移除URL参数依赖 feat(product): 添加机柜地址选择功能并重构商品列表页面 fix(wx): 修复余额获取逻辑并启用相关用户信息更新
This commit is contained in:
parent
e23719854e
commit
195749ad6e
|
@ -59,11 +59,11 @@ export function openCabinetApi(orderId: number, orderGoodsId: number, data: Open
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取用户余额接口 */
|
/** 获取用户余额接口 */
|
||||||
export function getBalanceApi(openid: string) {
|
export function getBalanceApi(corpid: string, openid: string) {
|
||||||
return request<ApiResponseData<GetBalanceResponse>>({
|
return request<ApiResponseData<GetBalanceResponse>>({
|
||||||
url: "payment/getBalance",
|
url: "payment/getBalance",
|
||||||
method: "get",
|
method: "get",
|
||||||
params: { openid }
|
params: { corpid, openid }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function getBalanceByQyUserid(corpid: string, userid: string) {
|
export function getBalanceByQyUserid(corpid: string, userid: string) {
|
||||||
|
|
|
@ -11,6 +11,8 @@ import Detail from "./components/detail.vue"
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useWxStore } from "@/pinia/stores/wx"
|
import { useWxStore } from "@/pinia/stores/wx"
|
||||||
import { bindQyUserApi } from "@/common/apis/ab98"
|
import { bindQyUserApi } from "@/common/apis/ab98"
|
||||||
|
import { getShopListApi } from "@/common/apis/shop"
|
||||||
|
import { ShopEntity } from "@/common/apis/shop/type"
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
@ -33,6 +35,11 @@ const headerHeight = ref(150)
|
||||||
// 滚动事件监听器存储数组
|
// 滚动事件监听器存储数组
|
||||||
let scrollListener: any[] = []
|
let scrollListener: any[] = []
|
||||||
|
|
||||||
|
// 显示选择商店列表
|
||||||
|
const showShopList = ref(true);
|
||||||
|
const shopList = ref<ShopEntity[]>([]);
|
||||||
|
const shopId = ref<number>(0);
|
||||||
|
|
||||||
// 商品详情弹窗控制
|
// 商品详情弹窗控制
|
||||||
const showDetailPopup = ref(false)
|
const showDetailPopup = ref(false)
|
||||||
// 当前查看的商品ID
|
// 当前查看的商品ID
|
||||||
|
@ -51,6 +58,18 @@ const idNum = ref('');
|
||||||
const showAb98BindPopup = ref(false);
|
const showAb98BindPopup = ref(false);
|
||||||
|
|
||||||
// 点击分类导航
|
// 点击分类导航
|
||||||
|
function handleShopSelect(selectedShopId: number) {
|
||||||
|
shopId.value = selectedShopId;
|
||||||
|
showShopList.value = false;
|
||||||
|
productStore.getGoods(selectedShopId);
|
||||||
|
cartStore.clearCart();
|
||||||
|
}
|
||||||
|
function handleBackToShopList() {
|
||||||
|
showShopList.value = true;
|
||||||
|
shopId.value = 0;
|
||||||
|
cartStore.clearCart();
|
||||||
|
}
|
||||||
|
|
||||||
function handleCategoryClick(index: number) {
|
function handleCategoryClick(index: number) {
|
||||||
activeCategory.value = index
|
activeCategory.value = index
|
||||||
}
|
}
|
||||||
|
@ -105,7 +124,7 @@ function getCartItemCount(cellId: number) {
|
||||||
|
|
||||||
function filterProductsByName(products: Product[], query: string) {
|
function filterProductsByName(products: Product[], query: string) {
|
||||||
if (!query) return products
|
if (!query) return products
|
||||||
return products.filter(p =>
|
return products.filter(p =>
|
||||||
p.name.toLowerCase().includes(query.toLowerCase())
|
p.name.toLowerCase().includes(query.toLowerCase())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -117,7 +136,15 @@ const currentProducts = computed(() => {
|
||||||
|
|
||||||
// 组件挂载时添加滚动监听
|
// 组件挂载时添加滚动监听
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
productStore.getGoods();
|
if (showShopList.value) {
|
||||||
|
getShopListApi(wxStore.corpid).then((res) => {
|
||||||
|
if (res?.code === 0 && res?.data?.length > 0) {
|
||||||
|
shopList.value = res.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
productStore.getGoods(shopId.value);
|
||||||
|
}
|
||||||
scrollListener.push(scrollContainer.value?.addEventListener("scroll", throttledScroll))
|
scrollListener.push(scrollContainer.value?.addEventListener("scroll", throttledScroll))
|
||||||
// scrollListener.push(scrollContainer.value?.addEventListener("scroll", throttledUpdate))
|
// scrollListener.push(scrollContainer.value?.addEventListener("scroll", throttledUpdate))
|
||||||
})
|
})
|
||||||
|
@ -137,14 +164,22 @@ function handleCheckout() {
|
||||||
// 路由更新时刷新数据
|
// 路由更新时刷新数据
|
||||||
watch(() => route.path, (newPath) => {
|
watch(() => route.path, (newPath) => {
|
||||||
if (newPath === '/') {
|
if (newPath === '/') {
|
||||||
productStore.getGoods()
|
if (showShopList.value) {
|
||||||
|
getShopListApi(wxStore.corpid).then((res) => {
|
||||||
|
if (res?.code === 0 && res?.data?.length > 0) {
|
||||||
|
shopList.value = res.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
productStore.getGoods(shopId.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}, { immediate: true });
|
||||||
|
|
||||||
let showAb98BindPopupOnce = false;
|
let showAb98BindPopupOnce = false;
|
||||||
watch(openid, async () => {
|
watch(openid, async () => {
|
||||||
if (openid.value && corpidLogin.value && !ab98User.value
|
if (openid.value && corpidLogin.value && !ab98User.value
|
||||||
&& !showAb98BindPopup.value && !showAb98BindPopupOnce) {
|
&& !showAb98BindPopup.value && !showAb98BindPopupOnce) {
|
||||||
// 显示绑定弹窗
|
// 显示绑定弹窗
|
||||||
showAb98BindPopup.value = true;
|
showAb98BindPopup.value = true;
|
||||||
showAb98BindPopupOnce = true;
|
showAb98BindPopupOnce = true;
|
||||||
|
@ -174,24 +209,49 @@ async function handleAb98Bind() {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="shop">
|
<div v-if="showShopList" class="shop-list">
|
||||||
|
<div class="shop-header" :style="{ height: `${headerHeight}px` }">
|
||||||
|
<van-image :src="`${publicPath}cover.png`" class="shop-cover" fit="cover" />
|
||||||
|
</div>
|
||||||
|
<div class="shop-prompt">
|
||||||
|
<van-cell title="请选择机柜地址:" center />
|
||||||
|
</div>
|
||||||
|
<van-row :gutter="[10, 10]" class="shop-row" justify="start">
|
||||||
|
<van-col span="12" class="shop-col">
|
||||||
|
<div class="shop-item" @click="handleShopSelect(0)">
|
||||||
|
<div class="shop-info">
|
||||||
|
<van-icon name="home-o" size="20" class="shop-icon" />
|
||||||
|
<div class="shop-name van-ellipsis">全部</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-col>
|
||||||
|
<van-col v-for="shop in shopList" :key="shop.shopId" span="12" class="shop-col">
|
||||||
|
<div class="shop-item" @click="handleShopSelect(shop.shopId)">
|
||||||
|
<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-if="!showShopList" class="shop">
|
||||||
<div class="shop-header" :style="{ height: `${headerHeight}px` }">
|
<div class="shop-header" :style="{ height: `${headerHeight}px` }">
|
||||||
<van-image :src="`${publicPath}cover.png`" class="shop-cover" fit="cover" />
|
<van-image :src="`${publicPath}cover.png`" class="shop-cover" fit="cover" />
|
||||||
</div>
|
</div>
|
||||||
<div class="product-container">
|
<div class="product-container">
|
||||||
<!-- 左侧分类导航 -->
|
<!-- 左侧分类导航 -->
|
||||||
<van-sidebar v-model="activeCategory" class="category-nav" @change="handleCategoryClick">
|
<div>
|
||||||
<van-sidebar-item v-for="label in labels" :key="label.id" :title="label.name" />
|
<van-button icon="revoke" type="default" class="showShopListBtn" @click="showShopList = true">重选地址</van-button>
|
||||||
</van-sidebar>
|
<van-sidebar v-model="activeCategory" class="category-nav" @change="handleCategoryClick">
|
||||||
|
<van-sidebar-item v-for="label in labels" :key="label.id" :title="label.name" />
|
||||||
|
</van-sidebar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 右侧商品列表 -->
|
<!-- 右侧商品列表 -->
|
||||||
<div ref="scrollContainer" class="product-list">
|
<div ref="scrollContainer" class="product-list">
|
||||||
<van-search
|
<van-search v-model="searchQuery" placeholder="搜索商品名称" shape="round" class="search-box" />
|
||||||
v-model="searchQuery"
|
|
||||||
placeholder="搜索商品名称"
|
|
||||||
shape="round"
|
|
||||||
class="search-box"
|
|
||||||
/>
|
|
||||||
<div class="category-section">
|
<div class="category-section">
|
||||||
<van-cell v-for="product in currentProducts" :key="product.id" class="product-item">
|
<van-cell v-for="product in currentProducts" :key="product.id" class="product-item">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
|
@ -222,7 +282,8 @@ async function handleAb98Bind() {
|
||||||
<div class="cart-actions">
|
<div class="cart-actions">
|
||||||
<van-button v-if="getCartItemCount(product.cellId)" size="mini" icon="minus"
|
<van-button v-if="getCartItemCount(product.cellId)" size="mini" icon="minus"
|
||||||
@click.stop="handleRemoveFromCart(product)" />
|
@click.stop="handleRemoveFromCart(product)" />
|
||||||
<span v-if="getCartItemCount(product.cellId)" class="cart-count">{{ getCartItemCount(product.cellId) }}</span>
|
<span v-if="getCartItemCount(product.cellId)" class="cart-count">{{ getCartItemCount(product.cellId)
|
||||||
|
}}</span>
|
||||||
<van-button size="mini" type="primary" class="add-cart-btn" icon="plus"
|
<van-button size="mini" type="primary" class="add-cart-btn" icon="plus"
|
||||||
:disabled="product.stock === 0" @click.stop="handleAddToCart(product)" :style="{
|
:disabled="product.stock === 0" @click.stop="handleAddToCart(product)" :style="{
|
||||||
opacity: product.stock === 0 ? 0.6 : 1,
|
opacity: product.stock === 0 ? 0.6 : 1,
|
||||||
|
@ -260,18 +321,9 @@ async function handleAb98Bind() {
|
||||||
<div style="text-align: center; font-size: 16px; font-weight: bold; margin-bottom: 16px;">请绑定汇邦云账号</div>
|
<div style="text-align: center; font-size: 16px; font-weight: bold; margin-bottom: 16px;">请绑定汇邦云账号</div>
|
||||||
<van-form @submit="handleAb98Bind">
|
<van-form @submit="handleAb98Bind">
|
||||||
<van-cell-group inset>
|
<van-cell-group inset>
|
||||||
<van-field
|
<van-field v-model="name" label="姓名" placeholder="请输入真实姓名" :rules="[{ required: true, message: '请填写姓名' }]" />
|
||||||
v-model="name"
|
<van-field v-model="idNum" label="身份证号" placeholder="请输入身份证号码"
|
||||||
label="姓名"
|
:rules="[{ required: true, message: '请填写身份证号' }]" />
|
||||||
placeholder="请输入真实姓名"
|
|
||||||
:rules="[{ required: true, message: '请填写姓名' }]"
|
|
||||||
/>
|
|
||||||
<van-field
|
|
||||||
v-model="idNum"
|
|
||||||
label="身份证号"
|
|
||||||
placeholder="请输入身份证号码"
|
|
||||||
:rules="[{ required: true, message: '请填写身份证号' }]"
|
|
||||||
/>
|
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
<div style="margin: 16px;">
|
<div style="margin: 16px;">
|
||||||
<van-button block type="primary" native-type="submit">
|
<van-button block type="primary" native-type="submit">
|
||||||
|
@ -305,6 +357,12 @@ async function handleAb98Bind() {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.showShopListBtn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.product-list {
|
.product-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -505,4 +563,54 @@ async function handleAb98Bind() {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shop-list {
|
||||||
|
.shop-prompt {
|
||||||
|
margin: 8px;
|
||||||
|
height: 44px !important;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-row {
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-col {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-item {
|
||||||
|
height: 60px !important;
|
||||||
|
padding: 12px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
|
||||||
|
.shop-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: start;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 2px 0 4px 2px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -234,12 +234,12 @@ async function handleSubmit() {
|
||||||
<van-icon v-if="selectedPayment === 'wechat'" name="success" class="check-icon" />
|
<van-icon v-if="selectedPayment === 'wechat'" name="success" class="check-icon" />
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|
||||||
<van-cell v-if="corpidLogin"
|
<van-cell v-if="balance && balance > 0"
|
||||||
:class="['payment-option', { selected: selectedPayment === 'balance', disabled: balance < totalPrice }]"
|
:class="['payment-option', { selected: selectedPayment === 'balance', disabled: balance < totalPrice }]"
|
||||||
@click="selectedPayment = 'balance'">
|
@click="selectedPayment = 'balance'">
|
||||||
<van-icon name="balance-o" class="method-icon" />
|
<van-icon name="balance-o" class="method-icon" />
|
||||||
<span class="method-label">
|
<span class="method-label">
|
||||||
余额支付
|
借呗支付
|
||||||
<span class="balance-amount">(当前:¥{{ balance.toFixed(2) }})</span>
|
<span class="balance-amount">(当前:¥{{ balance.toFixed(2) }})</span>
|
||||||
</span>
|
</span>
|
||||||
<div class="empty"></div>
|
<div class="empty"></div>
|
||||||
|
|
|
@ -21,14 +21,15 @@ export const useProductStore = defineStore("product", () => {
|
||||||
const shopId = ref<number|null>(null);
|
const shopId = ref<number|null>(null);
|
||||||
|
|
||||||
const getGoods = async (shopId_?: number) => {
|
const getGoods = async (shopId_?: number) => {
|
||||||
if (shopId_) {
|
if (shopId_ && shopId_ > 0) {
|
||||||
shopId.value = shopId_;
|
shopId.value = shopId_;
|
||||||
} else {
|
} else {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
shopId.value = null;
|
||||||
|
/* const urlParams = new URLSearchParams(window.location.search);
|
||||||
const shopIdParams = urlParams.get('shopId') || undefined;
|
const shopIdParams = urlParams.get('shopId') || undefined;
|
||||||
if (shopIdParams) {
|
if (shopIdParams) {
|
||||||
shopId.value = Number(shopIdParams);
|
shopId.value = Number(shopIdParams);
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -108,17 +108,17 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
balanceRes = await getBalanceByQyUserid(corpid.value, userid.value);
|
balanceRes = await getBalanceByQyUserid(corpid.value, userid.value);
|
||||||
} else {
|
} else {
|
||||||
corpid.value = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw";
|
corpid.value = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw";
|
||||||
// balanceRes = await getBalanceApi(openid.value)
|
balanceRes = await getBalanceApi(corpid.value, openid.value)
|
||||||
}
|
}
|
||||||
console.log('获取余额成功:', balanceRes)
|
console.log('获取余额成功:', balanceRes)
|
||||||
if (balanceRes && balanceRes.code == 0) {
|
if (balanceRes && balanceRes.code == 0) {
|
||||||
balance.value = balanceRes.data.balance;
|
balance.value = balanceRes.data.balance;
|
||||||
useBalance.value = balanceRes.data.useBalance;
|
useBalance.value = balanceRes.data.useBalance;
|
||||||
balanceLimit.value = balanceRes.data.balanceLimit;
|
balanceLimit.value = balanceRes.data.balanceLimit;
|
||||||
/* if (!userid.value) {
|
if (!userid.value) {
|
||||||
userid.value = balanceRes.data.userid;
|
userid.value = balanceRes.data.userid;
|
||||||
}
|
}
|
||||||
if (!corpid.value) {
|
/* if (!corpid.value) {
|
||||||
corpid.value = balanceRes.data.corpid;
|
corpid.value = balanceRes.data.corpid;
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ export function registerNavigationGuard(router: Router) {
|
||||||
if (corpid) {
|
if (corpid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* const isAdmin = urlParams.get('isAdmin') || undefined;
|
const isAdmin = urlParams.get('isAdmin') || undefined;
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
return true;
|
return true;
|
||||||
} */
|
}
|
||||||
|
|
||||||
// useAb98UserStore位置不能放在外面,否则会导致路由守卫无法正常工作
|
// useAb98UserStore位置不能放在外面,否则会导致路由守卫无法正常工作
|
||||||
const ab98UserStore = useAb98UserStore();
|
const ab98UserStore = useAb98UserStore();
|
||||||
|
|
Loading…
Reference in New Issue