Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b534a569f8 | |||
| b0f565103f | |||
| 5e33dd9847 |
@@ -2,8 +2,6 @@ import { useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
|
|
||||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import PageHeader from '@dukang/shared-ui/PageHeader';
|
|
||||||
|
|
||||||
import ChinaRegionPicker from '../components/ChinaRegionPicker';
|
import ChinaRegionPicker from '../components/ChinaRegionPicker';
|
||||||
|
|
||||||
import OssUploadField from '../components/OssUploadField';
|
import OssUploadField from '../components/OssUploadField';
|
||||||
@@ -576,11 +574,7 @@ export default function StoreCreatePage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<div className="partner-page-sticky">
|
<div className="partner-page-sticky partner-home--flush-top">
|
||||||
|
|
||||||
<PageHeader title="录入新门店" onBack={() => navigate('/stores')} />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<nav className="partner-stepper">
|
<nav className="partner-stepper">
|
||||||
|
|
||||||
@@ -980,7 +974,15 @@ export default function StoreCreatePage() {
|
|||||||
|
|
||||||
<label>银行卡号 *</label>
|
<label>银行卡号 *</label>
|
||||||
|
|
||||||
<input className="partner-field-input partner-field-input--block" placeholder="请输入16-19位银行卡号" value={form.bankAccountNo} onChange={(e) => patchForm({ bankAccountNo: e.target.value })} />
|
<input
|
||||||
|
className="partner-field-input partner-field-input--block"
|
||||||
|
inputMode="numeric"
|
||||||
|
autoComplete="cc-number"
|
||||||
|
maxLength={19}
|
||||||
|
placeholder="请输入16-19位银行卡号"
|
||||||
|
value={form.bankAccountNo}
|
||||||
|
onChange={(e) => patchForm({ bankAccountNo: e.target.value.replace(/\D/g, '').slice(0, 19) })}
|
||||||
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1116,7 +1118,11 @@ export default function StoreCreatePage() {
|
|||||||
|
|
||||||
<footer className="partner-sticky-footer">
|
<footer className="partner-sticky-footer">
|
||||||
|
|
||||||
{step > 1 && (
|
{step === 1 ? (
|
||||||
|
|
||||||
|
<button type="button" className="partner-btn-outline" onClick={() => navigate('/stores')} disabled={nextDisabled}>返回</button>
|
||||||
|
|
||||||
|
) : (
|
||||||
|
|
||||||
<button type="button" className="partner-btn-outline" onClick={() => goStep(step - 1)} disabled={nextDisabled}>上一步</button>
|
<button type="button" className="partner-btn-outline" onClick={() => goStep(step - 1)} disabled={nextDisabled}>上一步</button>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import PageHeader from '@dukang/shared-ui/PageHeader';
|
|
||||||
import AppImage from '@dukang/shared-ui/AppImage';
|
import AppImage from '@dukang/shared-ui/AppImage';
|
||||||
import { request } from '../lib/api';
|
import { request } from '../lib/api';
|
||||||
import { toastSuccess } from '../lib/toast';
|
import { toastSuccess } from '../lib/toast';
|
||||||
@@ -199,8 +198,7 @@ export default function StoreDetailPage() {
|
|||||||
|
|
||||||
if (loadError) {
|
if (loadError) {
|
||||||
return (
|
return (
|
||||||
<div className="partner-detail-page">
|
<div className="partner-detail-page partner-home--flush-top">
|
||||||
<PageHeader title="门店详情" onBack={() => navigate('/stores')} />
|
|
||||||
<div className="empty">{loadError}</div>
|
<div className="empty">{loadError}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -222,10 +220,8 @@ export default function StoreDetailPage() {
|
|||||||
const canOpen = canPartnerOpenStore(auditStatus);
|
const canOpen = canPartnerOpenStore(auditStatus);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="partner-detail-page">
|
<div className="partner-detail-page partner-home--flush-top">
|
||||||
<PageHeader title="门店详情" onBack={() => navigate('/stores')} />
|
<main style={{ padding: '12px 20px 16px' }}>
|
||||||
|
|
||||||
<main style={{ padding: '16px 20px' }}>
|
|
||||||
{actionError && <p className="partner-form-error" role="alert" style={{ marginBottom: 12 }}>{actionError}</p>}
|
{actionError && <p className="partner-form-error" role="alert" style={{ marginBottom: 12 }}>{actionError}</p>}
|
||||||
|
|
||||||
<section className="partner-form-card" style={{ margin: '0 0 16px' }}>
|
<section className="partner-form-card" style={{ margin: '0 0 16px' }}>
|
||||||
|
|||||||
@@ -3329,10 +3329,16 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.partner-home--flush-top.partner-store-page,
|
.partner-home--flush-top.partner-store-page,
|
||||||
.partner-home--flush-top.partner-center-page {
|
.partner-home--flush-top.partner-center-page,
|
||||||
|
.partner-home--flush-top.partner-detail-page,
|
||||||
|
.partner-home--flush-top.partner-page-sticky {
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.partner-home--flush-top.partner-page-sticky .partner-stepper {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.partner-home--flush-top .partner-sticky-filter {
|
.partner-home--flush-top .partner-sticky-filter {
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { View, Text } from '@tarojs/components';
|
import { View, Text, Image } from '@tarojs/components';
|
||||||
import Taro, { usePullDownRefresh, useRouter } from '@tarojs/taro';
|
import Taro, { usePullDownRefresh, useRouter } from '@tarojs/taro';
|
||||||
import PageShell from '../../components/PageShell';
|
import PageShell from '../../components/PageShell';
|
||||||
import SubPageHeader from '../../components/SubPageHeader';
|
import SubPageHeader from '../../components/SubPageHeader';
|
||||||
import { request, toast } from '../../lib/api';
|
import { request, toast } from '../../lib/api';
|
||||||
|
import { buildPayUrl } from '../../lib/checkout-nav';
|
||||||
|
|
||||||
const TABS = [
|
const TABS = [
|
||||||
{ key: 'all', label: '全部订单' },
|
{ key: 'all', label: '全部订单' },
|
||||||
@@ -30,6 +31,13 @@ function orderStatusLabel(tab: string, status?: string): string {
|
|||||||
return STATUS_LABELS[status] || status;
|
return STATUS_LABELS[status] || status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrderItem = {
|
||||||
|
productName?: string;
|
||||||
|
productImage?: string;
|
||||||
|
unitPrice?: number;
|
||||||
|
quantity?: number;
|
||||||
|
};
|
||||||
|
|
||||||
type OrderRow = {
|
type OrderRow = {
|
||||||
id: string;
|
id: string;
|
||||||
orderNo?: string;
|
orderNo?: string;
|
||||||
@@ -37,7 +45,9 @@ type OrderRow = {
|
|||||||
payAmount?: number;
|
payAmount?: number;
|
||||||
productName?: string;
|
productName?: string;
|
||||||
qty?: number;
|
qty?: number;
|
||||||
createdAt?: string;
|
quantity?: number;
|
||||||
|
originOrderId?: string | null;
|
||||||
|
items?: OrderItem[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function OrdersPage() {
|
export default function OrdersPage() {
|
||||||
@@ -71,6 +81,10 @@ export default function OrdersPage() {
|
|||||||
void loadOrders().finally(() => Taro.stopPullDownRefresh());
|
void loadOrders().finally(() => Taro.stopPullDownRefresh());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function goPay(orderId: string) {
|
||||||
|
Taro.navigateTo({ url: buildPayUrl({ orderId }) });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageShell variant="sub" className="orders-page">
|
<PageShell variant="sub" className="orders-page">
|
||||||
<SubPageHeader title="我的订单" />
|
<SubPageHeader title="我的订单" />
|
||||||
@@ -89,35 +103,62 @@ export default function OrdersPage() {
|
|||||||
{loading ? <View className="u-empty">加载中…</View> : null}
|
{loading ? <View className="u-empty">加载中…</View> : null}
|
||||||
{!loading && orders.length === 0 ? <View className="u-empty">暂无订单</View> : null}
|
{!loading && orders.length === 0 ? <View className="u-empty">暂无订单</View> : null}
|
||||||
{!loading &&
|
{!loading &&
|
||||||
orders.map((o) => (
|
orders.map((o) => {
|
||||||
<View
|
const item = o.items?.[0];
|
||||||
key={o.id}
|
const productName = item?.productName || o.productName || '杜康商品';
|
||||||
className="order-list-item"
|
const productImage = (item?.productImage || '').trim();
|
||||||
onClick={() => Taro.navigateTo({ url: `/pages/order-detail/index?id=${o.id}` })}
|
const qty = item?.quantity ?? o.quantity ?? o.qty ?? 1;
|
||||||
>
|
const unitPrice = Number(item?.unitPrice ?? 0);
|
||||||
<View className="order-list-head">
|
const canPay = o.status === 'PENDING_PAY' && !o.originOrderId;
|
||||||
<Text className="order-list-no">{o.orderNo || o.id}</Text>
|
|
||||||
<Text className="order-list-status">
|
return (
|
||||||
{orderStatusLabel(tab, o.status)}
|
<View
|
||||||
</Text>
|
key={o.id}
|
||||||
</View>
|
className="order-list-item"
|
||||||
<View className="order-list-body">
|
onClick={() => Taro.navigateTo({ url: `/pages/order-detail/index?id=${o.id}` })}
|
||||||
<View className="order-list-thumb" />
|
>
|
||||||
<View style={{ flex: 1 }}>
|
<View className="order-list-head">
|
||||||
<Text className="order-list-name">{o.productName || '杜康商品'}</Text>
|
<Text className="order-list-no">{o.orderNo || o.id}</Text>
|
||||||
<Text className="order-list-meta">
|
<Text className="order-list-status">
|
||||||
数量 {o.qty ?? 1} · {o.createdAt ? String(o.createdAt).slice(0, 10) : ''}
|
{orderStatusLabel(tab, o.status)}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
<View className="order-list-body">
|
||||||
|
<View className="order-list-thumb">
|
||||||
|
{productImage ? (
|
||||||
|
<Image className="order-list-thumb-img" src={productImage} mode="aspectFill" />
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<Text className="order-list-name">{productName}</Text>
|
||||||
|
<View className="order-list-meta-row">
|
||||||
|
<Text className="order-list-meta">数量 {qty}</Text>
|
||||||
|
<Text className="order-list-meta">单价 ¥{unitPrice.toFixed(2)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className="order-list-footer">
|
||||||
|
<View className="order-list-pay-amount">
|
||||||
|
<Text className="order-list-meta">实付</Text>
|
||||||
|
<Text className="order-product-price">
|
||||||
|
¥{Number(o.payAmount ?? 0).toFixed(2)}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
{canPay ? (
|
||||||
|
<View
|
||||||
|
className="order-list-pay-btn"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
goPay(o.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
付款
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="order-list-footer">
|
);
|
||||||
<Text className="order-list-meta">实付</Text>
|
})}
|
||||||
<Text className="order-product-price">
|
|
||||||
¥{Number(o.payAmount ?? 0).toFixed(2)}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
</PageShell>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default function RedeemPage() {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View className="redeem-amount-foot">
|
<View className="redeem-amount-foot">
|
||||||
<Text className="redeem-tips" style={{ margin: 0 }}>
|
<Text className="redeem-amount-hint">
|
||||||
最高可核销 ¥{formatMoney(redeemableMax)}
|
最高可核销 ¥{formatMoney(redeemableMax)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="redeem-fill-max" onClick={fillMaxAmount}>
|
<Text className="redeem-fill-max" onClick={fillMaxAmount}>
|
||||||
|
|||||||
@@ -314,6 +314,13 @@
|
|||||||
background: var(--color-surface-container);
|
background: var(--color-surface-container);
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-list-thumb-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-list-name {
|
.order-list-name {
|
||||||
@@ -323,6 +330,12 @@
|
|||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.order-list-meta-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.order-list-meta {
|
.order-list-meta {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -336,6 +349,28 @@
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
border-top: 1px solid var(--color-surface-container);
|
border-top: 1px solid var(--color-surface-container);
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-list-pay-amount {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-list-pay-btn {
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--color-heritage-red);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pay-status {
|
.pay-status {
|
||||||
|
|||||||
@@ -75,12 +75,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.redeem-tips {
|
.redeem-tips {
|
||||||
margin: 0 var(--space-page);
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 var(--space-page);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--color-subtle-gray);
|
color: var(--color-subtle-gray);
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redeem-amount-hint {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-subtle-gray);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
.redeem-amount-foot {
|
.redeem-amount-foot {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user