feat(clinic): 实现处方订单管理功能
- 新增处方订单列表展示组件 - 实现处方订单支付功能,调用统一支付接口 - 添加订单状态显示及待支付订单过滤逻辑 - 实现处方订单支付成功后状态更新 - 新增订单详情跳转和复制订单号功能 - 添加处方订单删除、编辑、详情操作 - 实现处方订单页面标题更新为"处方管理" - 新增处方订单页面样式优化,包括搜索框、按钮等样式 - 实现订单列表组件,支持订单状态筛选和分页加载 - 添加订单支付倒计时和订单状态标签显示 - 实现订单取消、确认收货等操作功能 - 新增订单再次购买、申请退款等扩展功能 - 实现订单物流查看和评价商品功能- 添加订单退款进度查看和撤销申请功能
This commit is contained in:
@@ -5,7 +5,7 @@ import type { ApiResult } from '@/api';
|
|||||||
* 统一支付
|
* 统一支付
|
||||||
*/
|
*/
|
||||||
export async function pay(data: any) {
|
export async function pay(data: any) {
|
||||||
const res = await request.post<ApiResult<any>>('/payment/create',data);
|
const res = await request.post<ApiResult<any>>('/payment/create-with-order',data);
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,8 +153,8 @@ export interface ShopOrder {
|
|||||||
* 订单商品项
|
* 订单商品项
|
||||||
*/
|
*/
|
||||||
export interface OrderGoodsItem {
|
export interface OrderGoodsItem {
|
||||||
goodsId: number;
|
goodsId?: number;
|
||||||
quantity: number;
|
quantity?: number;
|
||||||
skuId?: number;
|
skuId?: number;
|
||||||
specInfo?: string;
|
specInfo?: string;
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ export interface OrderGoodsItem {
|
|||||||
*/
|
*/
|
||||||
export interface OrderCreateRequest {
|
export interface OrderCreateRequest {
|
||||||
// 商品信息列表
|
// 商品信息列表
|
||||||
goodsItems: OrderGoodsItem[];
|
goodsItems?: OrderGoodsItem[];
|
||||||
// 收货地址ID
|
// 收货地址ID
|
||||||
addressId?: number;
|
addressId?: number;
|
||||||
// 支付方式
|
// 支付方式
|
||||||
@@ -185,8 +185,8 @@ export interface OrderCreateRequest {
|
|||||||
* 订单商品项
|
* 订单商品项
|
||||||
*/
|
*/
|
||||||
export interface OrderGoodsItem {
|
export interface OrderGoodsItem {
|
||||||
goodsId: number;
|
goodsId?: number;
|
||||||
quantity: number;
|
quantity?: number;
|
||||||
skuId?: number;
|
skuId?: number;
|
||||||
specInfo?: string;
|
specInfo?: string;
|
||||||
}
|
}
|
||||||
@@ -195,8 +195,10 @@ export interface OrderGoodsItem {
|
|||||||
* 创建订单请求
|
* 创建订单请求
|
||||||
*/
|
*/
|
||||||
export interface OrderCreateRequest {
|
export interface OrderCreateRequest {
|
||||||
|
// 订单编号
|
||||||
|
orderNo?: string;
|
||||||
// 商品信息列表
|
// 商品信息列表
|
||||||
goodsItems: OrderGoodsItem[];
|
goodsItems?: OrderGoodsItem[];
|
||||||
// 收货地址ID
|
// 收货地址ID
|
||||||
addressId?: number;
|
addressId?: number;
|
||||||
// 支付方式
|
// 支付方式
|
||||||
@@ -209,6 +211,8 @@ export interface OrderCreateRequest {
|
|||||||
deliveryType?: number;
|
deliveryType?: number;
|
||||||
// 自提店铺ID
|
// 自提店铺ID
|
||||||
selfTakeMerchantId?: number;
|
selfTakeMerchantId?: number;
|
||||||
|
// 订单类型
|
||||||
|
type?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Tag} from '@nutui
|
|||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
||||||
import {
|
import {
|
||||||
pageClinicPrescription,
|
pageClinicPrescription, updateClinicPrescription,
|
||||||
WxPayResult
|
WxPayResult
|
||||||
} from "@/api/clinic/clinicPrescription";
|
} from "@/api/clinic/clinicPrescription";
|
||||||
import {copyText} from "@/utils/common";
|
import {copyText} from "@/utils/common";
|
||||||
import {pay} from "@/api/payment";
|
import {createOrder} from "@/api/shop/shopOrder";
|
||||||
|
|
||||||
const ClinicPrescriptionList = () => {
|
const ClinicPrescriptionList = () => {
|
||||||
const [list, setList] = useState<ClinicPrescription[]>([])
|
const [list, setList] = useState<ClinicPrescription[]>([])
|
||||||
@@ -92,39 +92,20 @@ const ClinicPrescriptionList = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用统一支付接口
|
// 调用统一支付接口
|
||||||
const result = await pay(
|
const result = await createOrder(
|
||||||
// addressId: 10951,
|
|
||||||
// orderId: 0,
|
|
||||||
// deliveryType: 0,
|
|
||||||
// paymentType: 'JSAPI',
|
|
||||||
// amount: 1,
|
|
||||||
// subject: '开处方'
|
|
||||||
{
|
{
|
||||||
"paymentType": "WECHAT",
|
type: 1,
|
||||||
"amount": 100.00,
|
addressId: 10951,
|
||||||
"subject": "网站建设服务订单",
|
comments: '开方',
|
||||||
"description": "网站建设服务",
|
deliveryType: 0,
|
||||||
"orderInfo": {
|
payType: 1,
|
||||||
"type": 0,
|
goodsItems: [
|
||||||
"realName": "无",
|
|
||||||
"address": "无",
|
|
||||||
"addressId": 0,
|
|
||||||
"deliveryType": 0,
|
|
||||||
"channel": 0,
|
|
||||||
"merchantId": null,
|
|
||||||
"merchantName": null,
|
|
||||||
"couponId": null,
|
|
||||||
"comments": "网站建设服务订单",
|
|
||||||
"goodsItems": [
|
|
||||||
{
|
{
|
||||||
"goodsId": 10004,
|
goodsId: 10056,
|
||||||
"skuId": null,
|
quantity: 1
|
||||||
"quantity": 1,
|
|
||||||
"specInfo": null
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
console.log(result, 'resultresultresultresultresultresult')
|
console.log(result, 'resultresultresultresultresultresult')
|
||||||
|
|
||||||
@@ -144,6 +125,12 @@ const ClinicPrescriptionList = () => {
|
|||||||
// 支付成功
|
// 支付成功
|
||||||
console.log('支付成功,订单号:', result.orderNo);
|
console.log('支付成功,订单号:', result.orderNo);
|
||||||
|
|
||||||
|
await updateClinicPrescription({
|
||||||
|
id: item.id,
|
||||||
|
orderNo: result.orderNo,
|
||||||
|
status: 2
|
||||||
|
})
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '支付成功',
|
title: '支付成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
@@ -196,9 +183,9 @@ const ClinicPrescriptionList = () => {
|
|||||||
{list.map((item) => (
|
{list.map((item) => (
|
||||||
<CellGroup key={item.id} className="mb-3">
|
<CellGroup key={item.id} className="mb-3">
|
||||||
<Cell
|
<Cell
|
||||||
title={item.orderNo}
|
title={`${item.id}`}
|
||||||
extra={
|
extra={
|
||||||
<Tag type={'warning'} className="font-medium">待支付</Tag>
|
<Tag type={'warning'} className="font-medium">{item.status == 2 ? '已支付' : '待支付'}</Tag>
|
||||||
}
|
}
|
||||||
onClick={() => copyText(`${item.orderNo}`)}
|
onClick={() => copyText(`${item.orderNo}`)}
|
||||||
/>
|
/>
|
||||||
@@ -239,6 +226,7 @@ const ClinicPrescriptionList = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{item.status == 0 && (
|
||||||
<Cell>
|
<Cell>
|
||||||
<Space className="w-full justify-end">
|
<Space className="w-full justify-end">
|
||||||
<Button
|
<Button
|
||||||
@@ -249,6 +237,7 @@ const ClinicPrescriptionList = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</Cell>
|
</Cell>
|
||||||
|
)}
|
||||||
</CellGroup>
|
</CellGroup>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
201
src/clinic/clinicPrescription/_index.tsx
Normal file
201
src/clinic/clinicPrescription/_index.tsx
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
import {useState} from "react";
|
||||||
|
import Taro, {useDidShow} from '@tarojs/taro'
|
||||||
|
import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Tag} from '@nutui/nutui-react-taro'
|
||||||
|
import {Del, Edit} from '@nutui/icons-react-taro'
|
||||||
|
import {View, Text} from '@tarojs/components'
|
||||||
|
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
||||||
|
import {
|
||||||
|
pageClinicPrescription,
|
||||||
|
removeClinicPrescription
|
||||||
|
} from "@/api/clinic/clinicPrescription";
|
||||||
|
import FixedButton from "@/components/FixedButton";
|
||||||
|
import {copyText} from "@/utils/common";
|
||||||
|
|
||||||
|
const ClinicPrescriptionList = () => {
|
||||||
|
const [list, setList] = useState<ClinicPrescription[]>([])
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
setLoading(true)
|
||||||
|
pageClinicPrescription({
|
||||||
|
// 添加查询条件
|
||||||
|
doctorId: Taro.getStorageSync('UserId'),
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
setList(data?.list || [])
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '获取数据失败',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDel = async (item: ClinicPrescription) => {
|
||||||
|
const res = await Taro.showModal({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确定要删除处方编号「${item.orderNo}」吗?`,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res.confirm) {
|
||||||
|
try {
|
||||||
|
await removeClinicPrescription(item.id)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '删除成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
reload();
|
||||||
|
} catch (error) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '删除失败',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onEdit = (item: ClinicPrescription) => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/clinic/clinicPrescription/add?id=${item.id}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDetail = (item: ClinicPrescription) => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/clinic/clinicPrescription/detail?id=${item.id}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSexName = (sex?: number) => {
|
||||||
|
return sex === 0 ? '男' : sex === 1 ? '女' : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
useDidShow(() => {
|
||||||
|
reload()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (list.length === 0 && !loading) {
|
||||||
|
return (
|
||||||
|
<ConfigProvider>
|
||||||
|
<View className={'h-full flex flex-col justify-center items-center'} style={{
|
||||||
|
height: 'calc(100vh - 300px)',
|
||||||
|
}}>
|
||||||
|
<Empty
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
}}
|
||||||
|
description="暂无处方数据"
|
||||||
|
/>
|
||||||
|
<Space style={{marginTop: '20px'}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
|
||||||
|
>
|
||||||
|
新增处方
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</View>
|
||||||
|
</ConfigProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View className="p-3">
|
||||||
|
{list.map((item) => (
|
||||||
|
<CellGroup key={item.id} className="mb-3">
|
||||||
|
<Cell
|
||||||
|
title={item.orderNo}
|
||||||
|
extra={
|
||||||
|
<Tag type={'warning'} className="font-medium">待支付</Tag>
|
||||||
|
}
|
||||||
|
onClick={() => copyText(`${item.orderNo}`)}
|
||||||
|
/>
|
||||||
|
<Cell
|
||||||
|
title={'患者名称'}
|
||||||
|
extra={
|
||||||
|
<Space>
|
||||||
|
<Text className="font-medium">{item.realName}</Text>
|
||||||
|
<Text className="font-medium">{item.age}岁</Text>
|
||||||
|
<Text className="font-medium">{getSexName(item.sex)}</Text>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/*<Cell*/}
|
||||||
|
{/* title="处方类型"*/}
|
||||||
|
{/* extra={*/}
|
||||||
|
{/* <Tag type="info">*/}
|
||||||
|
{/* {getPrescriptionTypeText(item.prescriptionType)}*/}
|
||||||
|
{/* </Tag>*/}
|
||||||
|
{/* }*/}
|
||||||
|
{/*/>*/}
|
||||||
|
{item.diagnosis && (
|
||||||
|
<Cell
|
||||||
|
title="诊断结果"
|
||||||
|
extra={
|
||||||
|
<Text className="text-gray-600 text-sm">
|
||||||
|
{item.diagnosis.length > 20
|
||||||
|
? `${item.diagnosis.substring(0, 20)}...`
|
||||||
|
: item.diagnosis}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Cell
|
||||||
|
title="订单金额"
|
||||||
|
extra={
|
||||||
|
<Text className="text-red-500 font-medium">
|
||||||
|
¥{item.orderPrice || '0.00'}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Cell
|
||||||
|
title="创建时间"
|
||||||
|
extra={
|
||||||
|
<Text className="text-gray-500 text-xs">
|
||||||
|
{item.createTime}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Cell>
|
||||||
|
<Space className="w-full justify-end">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
icon={<Edit/>}
|
||||||
|
onClick={() => onDetail(item)}
|
||||||
|
>
|
||||||
|
详情
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
icon={<Edit/>}
|
||||||
|
onClick={() => onEdit(item)}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
icon={<Del/>}
|
||||||
|
onClick={() => onDel(item)}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Cell>
|
||||||
|
</CellGroup>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<FixedButton
|
||||||
|
text="开处方"
|
||||||
|
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ClinicPrescriptionList;
|
||||||
806
src/clinic/clinicPrescription/components/OrderList.tsx
Normal file
806
src/clinic/clinicPrescription/components/OrderList.tsx
Normal file
@@ -0,0 +1,806 @@
|
|||||||
|
import {Avatar, Cell, Space, Empty, Tabs, Button, TabPane, Image, Dialog} from '@nutui/nutui-react-taro'
|
||||||
|
import {useEffect, useState, useCallback, CSSProperties} from "react";
|
||||||
|
import {View, Text} from '@tarojs/components'
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import {pageShopOrder, updateShopOrder, createOrder} from "@/api/shop/shopOrder";
|
||||||
|
import {ShopOrder, ShopOrderParam} from "@/api/shop/shopOrder/model";
|
||||||
|
import {listShopOrderGoods} from "@/api/shop/shopOrderGoods";
|
||||||
|
import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model";
|
||||||
|
import {copyText} from "@/utils/common";
|
||||||
|
import PaymentCountdown from "@/components/PaymentCountdown";
|
||||||
|
import {PaymentType} from "@/utils/payment";
|
||||||
|
import {goTo} from "@/utils/navigation";
|
||||||
|
import {pageClinicPrescription} from "@/api/clinic/clinicPrescription";
|
||||||
|
|
||||||
|
// 判断订单是否支付已过期
|
||||||
|
const isPaymentExpired = (createTime: string, timeoutHours: number = 24): boolean => {
|
||||||
|
if (!createTime) return false;
|
||||||
|
const createTimeObj = dayjs(createTime);
|
||||||
|
const expireTime = createTimeObj.add(timeoutHours, 'hour');
|
||||||
|
const now = dayjs();
|
||||||
|
return now.isAfter(expireTime);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInfiniteUlStyle = (showSearch: boolean = false): CSSProperties => ({
|
||||||
|
marginTop: showSearch ? '0' : '0', // 如果显示搜索框,增加更多的上边距
|
||||||
|
height: showSearch ? '75vh' : '84vh', // 相应调整高度
|
||||||
|
width: '100%',
|
||||||
|
padding: '0',
|
||||||
|
overflowY: 'auto',
|
||||||
|
overflowX: 'hidden'
|
||||||
|
// 注意:小程序不支持 boxShadow
|
||||||
|
})
|
||||||
|
|
||||||
|
// 统一的订单状态标签配置,与后端 statusFilter 保持一致
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
key: '全部',
|
||||||
|
title: '全部',
|
||||||
|
description: '所有订单',
|
||||||
|
statusFilter: -1 // 使用-1表示全部订单
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
key: '待付款',
|
||||||
|
title: '待付款',
|
||||||
|
description: '等待付款的订单',
|
||||||
|
statusFilter: 0 // 对应后端:pay_status = false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 2,
|
||||||
|
key: '待发货',
|
||||||
|
title: '待发货',
|
||||||
|
description: '已付款待发货的订单',
|
||||||
|
statusFilter: 1 // 对应后端:pay_status = true AND delivery_status = 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 3,
|
||||||
|
key: '待收货',
|
||||||
|
title: '待收货',
|
||||||
|
description: '已发货待收货的订单',
|
||||||
|
statusFilter: 3 // 对应后端:pay_status = true AND delivery_status = 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 4,
|
||||||
|
key: '已完成',
|
||||||
|
title: '已完成',
|
||||||
|
description: '已完成的订单',
|
||||||
|
statusFilter: 5 // 对应后端:order_status = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 5,
|
||||||
|
key: '退货/售后',
|
||||||
|
title: '退货/售后',
|
||||||
|
description: '退货/售后的订单',
|
||||||
|
statusFilter: 6 // 对应后端:order_status = 6 (已退款)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 扩展订单接口,包含商品信息
|
||||||
|
interface OrderWithGoods extends ShopOrder {
|
||||||
|
orderGoods?: ShopOrderGoods[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrderListProps {
|
||||||
|
onReload?: () => void;
|
||||||
|
searchParams?: ShopOrderParam;
|
||||||
|
showSearch?: boolean;
|
||||||
|
onSearchParamsChange?: (params: ShopOrderParam) => void; // 新增:通知父组件参数变化
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderList(props: OrderListProps) {
|
||||||
|
const [list, setList] = useState<OrderWithGoods[]>([])
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
const [hasMore, setHasMore] = useState(true)
|
||||||
|
// 根据传入的statusFilter设置初始tab索引
|
||||||
|
const getInitialTabIndex = () => {
|
||||||
|
if (props.searchParams?.statusFilter !== undefined) {
|
||||||
|
const tab = tabs.find(t => t.statusFilter === props.searchParams?.statusFilter);
|
||||||
|
return tab ? tab.index : 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
const [tapIndex, setTapIndex] = useState<number>(() => {
|
||||||
|
const initialIndex = getInitialTabIndex();
|
||||||
|
console.log('初始化tapIndex:', initialIndex, '对应statusFilter:', props.searchParams?.statusFilter);
|
||||||
|
return initialIndex;
|
||||||
|
})
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [cancelDialogVisible, setCancelDialogVisible] = useState(false)
|
||||||
|
const [orderToCancel, setOrderToCancel] = useState<ShopOrder | null>(null)
|
||||||
|
const [confirmReceiveDialogVisible, setConfirmReceiveDialogVisible] = useState(false)
|
||||||
|
const [orderToConfirmReceive, setOrderToConfirmReceive] = useState<ShopOrder | null>(null)
|
||||||
|
|
||||||
|
// 获取订单状态文本
|
||||||
|
const getOrderStatusText = (order: ShopOrder) => {
|
||||||
|
|
||||||
|
// 优先检查订单状态
|
||||||
|
if (order.orderStatus === 2) return '已取消';
|
||||||
|
if (order.orderStatus === 4) return '退款申请中';
|
||||||
|
if (order.orderStatus === 5) return '退款被拒绝';
|
||||||
|
if (order.orderStatus === 6) return '退款成功';
|
||||||
|
if (order.orderStatus === 7) return '客户端申请退款';
|
||||||
|
|
||||||
|
// 检查支付状态 (payStatus为boolean类型,false/0表示未付款,true/1表示已付款)
|
||||||
|
if (!order.payStatus) return '等待买家付款';
|
||||||
|
|
||||||
|
// 已付款后检查发货状态
|
||||||
|
if (order.deliveryStatus === 10) return '待发货';
|
||||||
|
if (order.deliveryStatus === 20) return '待收货';
|
||||||
|
if (order.deliveryStatus === 30) return '已完成';
|
||||||
|
|
||||||
|
// 最后检查订单完成状态
|
||||||
|
if (order.orderStatus === 1) return '已完成';
|
||||||
|
if (order.orderStatus === 0) return '未使用';
|
||||||
|
|
||||||
|
return '未知状态';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取订单状态颜色
|
||||||
|
const getOrderStatusColor = (order: ShopOrder) => {
|
||||||
|
// 优先检查订单状态
|
||||||
|
if (order.orderStatus === 2) return 'text-gray-500'; // 已取消
|
||||||
|
if (order.orderStatus === 4) return 'text-orange-500'; // 退款申请中
|
||||||
|
if (order.orderStatus === 5) return 'text-red-500'; // 退款被拒绝
|
||||||
|
if (order.orderStatus === 6) return 'text-green-500'; // 退款成功
|
||||||
|
if (order.orderStatus === 7) return 'text-orange-500'; // 客户端申请退款
|
||||||
|
|
||||||
|
// 检查支付状态
|
||||||
|
if (!order.payStatus) return 'text-orange-500'; // 等待买家付款
|
||||||
|
|
||||||
|
// 已付款后检查发货状态
|
||||||
|
if (order.deliveryStatus === 10) return 'text-blue-500'; // 待发货
|
||||||
|
if (order.deliveryStatus === 20) return 'text-purple-500'; // 待收货
|
||||||
|
if (order.deliveryStatus === 30) return 'text-green-500'; // 已收货
|
||||||
|
|
||||||
|
// 最后检查订单完成状态
|
||||||
|
if (order.orderStatus === 1) return 'text-green-600'; // 已完成
|
||||||
|
if (order.orderStatus === 0) return 'text-gray-500'; // 未使用
|
||||||
|
|
||||||
|
return 'text-gray-600'; // 默认颜色
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用后端统一的 statusFilter 进行筛选
|
||||||
|
const getOrderStatusParams = (index: string | number) => {
|
||||||
|
let params: ShopOrderParam = {};
|
||||||
|
// 添加用户ID过滤
|
||||||
|
params.userId = Taro.getStorageSync('UserId');
|
||||||
|
|
||||||
|
// 获取当前tab的statusFilter配置
|
||||||
|
const currentTab = tabs.find(tab => tab.index === Number(index));
|
||||||
|
if (currentTab && currentTab.statusFilter !== undefined) {
|
||||||
|
params.statusFilter = currentTab.statusFilter;
|
||||||
|
}
|
||||||
|
// 注意:当statusFilter为undefined时,不要添加到params中,这样API请求就不会包含这个参数
|
||||||
|
|
||||||
|
console.log(`Tab ${index} (${currentTab?.title}) 筛选参数:`, params);
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
const reload = useCallback(async (resetPage = false, targetPage?: number) => {
|
||||||
|
setLoading(true);
|
||||||
|
setError(null); // 清除之前的错误
|
||||||
|
const currentPage = resetPage ? 1 : (targetPage || page);
|
||||||
|
const statusParams = getOrderStatusParams(tapIndex);
|
||||||
|
// 合并搜索条件,tab的statusFilter优先级更高
|
||||||
|
const searchConditions: any = {
|
||||||
|
page: currentPage,
|
||||||
|
type: 1,
|
||||||
|
userId: statusParams.userId, // 用户ID
|
||||||
|
...props.searchParams, // 搜索关键词等其他条件
|
||||||
|
};
|
||||||
|
|
||||||
|
// statusFilter总是添加到搜索条件中(包括-1表示全部)
|
||||||
|
if (statusParams.statusFilter !== undefined) {
|
||||||
|
searchConditions.statusFilter = statusParams.statusFilter;
|
||||||
|
}
|
||||||
|
console.log('订单筛选条件:', {
|
||||||
|
tapIndex,
|
||||||
|
statusParams,
|
||||||
|
searchConditions,
|
||||||
|
finalStatusFilter: searchConditions.statusFilter
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await pageClinicPrescription(searchConditions);
|
||||||
|
let newList: OrderWithGoods[];
|
||||||
|
|
||||||
|
if (res?.list && res?.list.length > 0) {
|
||||||
|
// 使用函数式更新避免依赖 list
|
||||||
|
setList(res?.list);
|
||||||
|
|
||||||
|
// 正确判断是否还有更多数据
|
||||||
|
const hasMoreData = res.list.length >= 10; // 假设每页10条数据
|
||||||
|
setHasMore(hasMoreData);
|
||||||
|
} else {
|
||||||
|
setList(prevList => resetPage ? [] : prevList);
|
||||||
|
setHasMore(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPage(currentPage);
|
||||||
|
setLoading(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载订单失败:', error);
|
||||||
|
setLoading(false);
|
||||||
|
setError('加载订单失败,请重试');
|
||||||
|
// 添加错误提示
|
||||||
|
Taro.showToast({
|
||||||
|
title: '加载失败,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [tapIndex, page, props.searchParams]); // 移除 list 依赖
|
||||||
|
|
||||||
|
const reloadMore = useCallback(async () => {
|
||||||
|
if (loading || !hasMore) return; // 防止重复加载
|
||||||
|
const nextPage = page + 1;
|
||||||
|
setPage(nextPage);
|
||||||
|
await reload(false, nextPage);
|
||||||
|
}, [loading, hasMore, page, reload]);
|
||||||
|
|
||||||
|
// 确认收货 - 显示确认对话框
|
||||||
|
const confirmReceive = (order: ShopOrder) => {
|
||||||
|
setOrderToConfirmReceive(order);
|
||||||
|
setConfirmReceiveDialogVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认收货 - 执行收货操作
|
||||||
|
const handleConfirmReceive = async () => {
|
||||||
|
if (!orderToConfirmReceive) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setConfirmReceiveDialogVisible(false);
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...orderToConfirmReceive,
|
||||||
|
deliveryStatus: 30, // 已收货
|
||||||
|
orderStatus: 1 // 已完成
|
||||||
|
});
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: '确认收货成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
await reload(true); // 重新加载列表
|
||||||
|
props.onReload?.(); // 通知父组件刷新
|
||||||
|
|
||||||
|
// 清空状态
|
||||||
|
setOrderToConfirmReceive(null);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('确认收货失败:', error);
|
||||||
|
Taro.showToast({
|
||||||
|
title: '确认收货失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
// 重新显示对话框
|
||||||
|
setConfirmReceiveDialogVisible(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消确认收货对话框
|
||||||
|
const handleCancelReceiveDialog = () => {
|
||||||
|
setConfirmReceiveDialogVisible(false);
|
||||||
|
setOrderToConfirmReceive(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 申请退款 (待发货状态)
|
||||||
|
const applyRefund = (order: ShopOrder) => {
|
||||||
|
// 跳转到退款申请页面
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/user/order/refund/index?orderId=${order.orderId}&orderNo=${order.orderNo}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查看物流 (待收货状态)
|
||||||
|
const viewLogistics = (order: ShopOrder) => {
|
||||||
|
// 跳转到物流查询页面
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/user/order/logistics/index?orderId=${order.orderId}&orderNo=${order.orderNo}&expressNo=${order.transactionId || ''}&expressCompany=SF`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 再次购买 (已完成状态)
|
||||||
|
const buyAgain = (order: ShopOrder) => {
|
||||||
|
console.log('再次购买:', order);
|
||||||
|
goTo(`/shop/orderConfirm/index?goodsId=${order.orderGoods[0].goodsId}`)
|
||||||
|
// Taro.showToast({
|
||||||
|
// title: '再次购买功能开发中',
|
||||||
|
// icon: 'none'
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 评价商品 (已完成状态)
|
||||||
|
const evaluateGoods = (order: ShopOrder) => {
|
||||||
|
// 跳转到评价页面
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/user/order/evaluate/index?orderId=${order.orderId}&orderNo=${order.orderNo}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查看进度 (退款/售后状态)
|
||||||
|
const viewProgress = (order: ShopOrder) => {
|
||||||
|
// 根据订单状态确定售后类型
|
||||||
|
let afterSaleType = 'refund' // 默认退款
|
||||||
|
|
||||||
|
if (order.orderStatus === 4) {
|
||||||
|
afterSaleType = 'refund' // 退款申请中
|
||||||
|
} else if (order.orderStatus === 7) {
|
||||||
|
afterSaleType = 'return' // 退货申请中
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到售后进度页面
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/user/order/progress/index?orderId=${order.orderId}&orderNo=${order.orderNo}&type=${afterSaleType}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 撤销申请 (退款/售后状态)
|
||||||
|
const cancelApplication = (order: ShopOrder) => {
|
||||||
|
console.log('撤销申请:', order);
|
||||||
|
Taro.showToast({
|
||||||
|
title: '撤销申请功能开发中',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消订单
|
||||||
|
const cancelOrder = (order: ShopOrder) => {
|
||||||
|
setOrderToCancel(order);
|
||||||
|
setCancelDialogVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认取消订单
|
||||||
|
const handleConfirmCancel = async () => {
|
||||||
|
if (!orderToCancel) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setCancelDialogVisible(false);
|
||||||
|
|
||||||
|
// 更新订单状态为已取消,而不是删除订单
|
||||||
|
await updateShopOrder({
|
||||||
|
...orderToCancel,
|
||||||
|
orderStatus: 2 // 已取消
|
||||||
|
});
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: '订单已取消',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
void reload(true); // 重新加载列表
|
||||||
|
props.onReload?.(); // 通知父组件刷新
|
||||||
|
} catch (error) {
|
||||||
|
console.error('取消订单失败:', error);
|
||||||
|
Taro.showToast({
|
||||||
|
title: '取消订单失败',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setOrderToCancel(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消对话框的取消操作
|
||||||
|
const handleCancelDialog = () => {
|
||||||
|
setCancelDialogVisible(false);
|
||||||
|
setOrderToCancel(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 立即支付
|
||||||
|
const payOrder = async (order: ShopOrder) => {
|
||||||
|
try {
|
||||||
|
if (!order.orderId || !order.orderNo) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '订单信息错误',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单是否已过期
|
||||||
|
if (order.createTime && isPaymentExpired(order.createTime)) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '订单已过期,无法支付',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查订单状态
|
||||||
|
if (order.payStatus) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '订单已支付',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order.orderStatus === 2) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '订单已取消,无法支付',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Taro.showLoading({title: '发起支付...'});
|
||||||
|
|
||||||
|
// 构建商品数据
|
||||||
|
const goodsItems = order.orderGoods?.map(goods => ({
|
||||||
|
goodsId: goods.goodsId,
|
||||||
|
quantity: goods.totalNum || 1
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
// 对于已存在的订单,我们需要重新发起支付
|
||||||
|
// 构建支付请求数据,包含完整的商品信息
|
||||||
|
const paymentData = {
|
||||||
|
orderId: order.orderId,
|
||||||
|
orderNo: order.orderNo,
|
||||||
|
goodsItems: goodsItems,
|
||||||
|
addressId: order.addressId,
|
||||||
|
payType: PaymentType.WECHAT
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('重新支付数据:', paymentData);
|
||||||
|
|
||||||
|
// 直接调用createOrder API进行重新支付
|
||||||
|
const result = await createOrder(paymentData as any);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw new Error('支付发起失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证微信支付必要参数
|
||||||
|
if (!result.timeStamp || !result.nonceStr || !result.package || !result.paySign) {
|
||||||
|
throw new Error('微信支付参数不完整');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用微信支付
|
||||||
|
await Taro.requestPayment({
|
||||||
|
timeStamp: result.timeStamp,
|
||||||
|
nonceStr: result.nonceStr,
|
||||||
|
package: result.package,
|
||||||
|
signType: (result.signType || 'MD5') as 'MD5' | 'HMAC-SHA256',
|
||||||
|
paySign: result.paySign,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 支付成功
|
||||||
|
Taro.showToast({
|
||||||
|
title: '支付成功',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重新加载订单列表
|
||||||
|
void reload(true);
|
||||||
|
props.onReload?.();
|
||||||
|
|
||||||
|
// 跳转到订单页面
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.navigateTo({url: '/user/order/order'});
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('支付失败:', error);
|
||||||
|
|
||||||
|
let errorMessage = '支付失败,请重试';
|
||||||
|
if (error.message) {
|
||||||
|
if (error.message.includes('cancel')) {
|
||||||
|
errorMessage = '用户取消支付';
|
||||||
|
} else if (error.message.includes('余额不足')) {
|
||||||
|
errorMessage = '账户余额不足';
|
||||||
|
} else {
|
||||||
|
errorMessage = error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: errorMessage,
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
Taro.hideLoading();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void reload(true); // 首次加载或tab切换时重置页码
|
||||||
|
}, [tapIndex]); // 只监听tapIndex变化,避免reload依赖循环
|
||||||
|
|
||||||
|
// 监听外部statusFilter变化,同步更新tab索引
|
||||||
|
useEffect(() => {
|
||||||
|
// 获取当前的statusFilter,如果未定义则默认为-1(全部)
|
||||||
|
const currentStatusFilter = props.searchParams?.statusFilter !== undefined
|
||||||
|
? props.searchParams.statusFilter
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
const tab = tabs.find(t => t.statusFilter === currentStatusFilter);
|
||||||
|
const targetTabIndex = tab ? tab.index : 0;
|
||||||
|
|
||||||
|
console.log('外部statusFilter变化:', {
|
||||||
|
statusFilter: currentStatusFilter,
|
||||||
|
originalStatusFilter: props.searchParams?.statusFilter,
|
||||||
|
currentTapIndex: tapIndex,
|
||||||
|
targetTabIndex,
|
||||||
|
shouldUpdate: targetTabIndex !== tapIndex
|
||||||
|
});
|
||||||
|
|
||||||
|
if (targetTabIndex !== tapIndex) {
|
||||||
|
setTapIndex(targetTabIndex);
|
||||||
|
// 不需要调用reload,因为tapIndex变化会触发reload
|
||||||
|
}
|
||||||
|
}, [props.searchParams?.statusFilter, tapIndex]); // 监听statusFilter变化
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tabs
|
||||||
|
align={'left'}
|
||||||
|
className={'fixed left-0'}
|
||||||
|
style={{
|
||||||
|
zIndex: 998,
|
||||||
|
borderBottom: '1px solid #e5e5e5'
|
||||||
|
}}
|
||||||
|
tabStyle={{
|
||||||
|
backgroundColor: '#ffffff'
|
||||||
|
// 注意:小程序不支持 boxShadow
|
||||||
|
}}
|
||||||
|
value={tapIndex}
|
||||||
|
onChange={(paneKey) => {
|
||||||
|
console.log('Tab切换:', paneKey, '类型:', typeof paneKey);
|
||||||
|
const newTapIndex = Number(paneKey);
|
||||||
|
setTapIndex(newTapIndex);
|
||||||
|
|
||||||
|
// 通知父组件更新 searchParams.statusFilter
|
||||||
|
const currentTab = tabs.find(tab => tab.index === newTapIndex);
|
||||||
|
if (currentTab && props.onSearchParamsChange) {
|
||||||
|
const newSearchParams = {
|
||||||
|
...props.searchParams,
|
||||||
|
statusFilter: currentTab.statusFilter
|
||||||
|
};
|
||||||
|
console.log('通知父组件更新searchParams:', newSearchParams);
|
||||||
|
props.onSearchParamsChange(newSearchParams);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
tabs?.map((item, _) => {
|
||||||
|
return (
|
||||||
|
<TabPane
|
||||||
|
key={item.index}
|
||||||
|
title={loading && tapIndex === item.index ? `${item.title}...` : item.title}
|
||||||
|
></TabPane>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Tabs>
|
||||||
|
<View style={getInfiniteUlStyle(props.showSearch)} id="scroll">
|
||||||
|
{error ? (
|
||||||
|
<View className="flex flex-col items-center justify-center h-64">
|
||||||
|
<View className="text-gray-500 mb-4">{error}</View>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => reload(true)}
|
||||||
|
>
|
||||||
|
重新加载
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<InfiniteLoading
|
||||||
|
target="scroll"
|
||||||
|
hasMore={hasMore}
|
||||||
|
onLoadMore={reloadMore}
|
||||||
|
onScroll={() => {
|
||||||
|
|
||||||
|
}}
|
||||||
|
onScrollToUpper={() => {
|
||||||
|
|
||||||
|
}}
|
||||||
|
loadingText={
|
||||||
|
<>
|
||||||
|
加载中
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
loadMoreText={
|
||||||
|
list.length === 0 ? (
|
||||||
|
<Empty style={{backgroundColor: 'transparent'}} description="您还没有订单哦"/>
|
||||||
|
) : (
|
||||||
|
<View className={'h-24'}>
|
||||||
|
没有更多了
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
{/* 订单列表 */}
|
||||||
|
{list.length > 0 && list
|
||||||
|
?.filter((item) => {
|
||||||
|
// 如果是待付款标签页(tapIndex === 1),过滤掉支付已过期的订单
|
||||||
|
if (tapIndex === 1 && !item.payStatus && item.orderStatus !== 2 && item.createTime) {
|
||||||
|
return !isPaymentExpired(item.createTime);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Cell key={index} style={{padding: '16px'}}
|
||||||
|
onClick={() => Taro.navigateTo({url: `/shop/orderDetail/index?orderId=${item.orderId}`})}>
|
||||||
|
<Space direction={'vertical'} className={'w-full flex flex-col'}>
|
||||||
|
<View className={'order-no flex justify-between'}>
|
||||||
|
<View className={'flex items-center'}>
|
||||||
|
<Text className={'text-gray-600 font-bold text-sm'}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
copyText(`${item.orderNo}`)
|
||||||
|
}}>{item.orderNo}</Text>
|
||||||
|
</View>
|
||||||
|
{/* 右侧显示合并的状态和倒计时 */}
|
||||||
|
<View className={`${getOrderStatusColor(item)} font-medium`}>
|
||||||
|
{!item.payStatus && item.orderStatus !== 2 ? (
|
||||||
|
<PaymentCountdown
|
||||||
|
createTime={item.createTime}
|
||||||
|
payStatus={item.payStatus}
|
||||||
|
realTime={false}
|
||||||
|
showSeconds={false}
|
||||||
|
mode={'badge'}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
getOrderStatusText(item)
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</View>
|
||||||
|
|
||||||
|
{/* 商品信息 */}
|
||||||
|
<View className={'goods-info'}>
|
||||||
|
{item.orderGoods && item.orderGoods.length > 0 ? (
|
||||||
|
item.orderGoods.map((goods, goodsIndex) => (
|
||||||
|
<View key={goodsIndex} className={'flex items-center mb-2'}>
|
||||||
|
<Image
|
||||||
|
src={goods.image || '/default-goods.png'}
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
lazyLoad={false}
|
||||||
|
className={'rounded'}
|
||||||
|
/>
|
||||||
|
<View className={'ml-2 flex flex-col flex-1'}>
|
||||||
|
<Text className={'text-sm font-bold'}>{goods.goodsName}</Text>
|
||||||
|
{goods.spec && <Text className={'text-gray-500 text-xs'}>规格:{goods.spec}</Text>}
|
||||||
|
<Text className={'text-gray-500 text-xs'}>数量:{goods.totalNum}</Text>
|
||||||
|
</View>
|
||||||
|
<Text className={'text-sm'}>¥{goods.price}</Text>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<View className={'flex items-center'}>
|
||||||
|
<Avatar
|
||||||
|
src='/default-goods.png'
|
||||||
|
size={'50'}
|
||||||
|
shape={'square'}
|
||||||
|
/>
|
||||||
|
<View className={'ml-2'}>
|
||||||
|
<Text className={'text-sm'}>{item.title || '订单商品'}</Text>
|
||||||
|
<Text className={'text-gray-400 text-xs'}>{item.totalNum}件商品</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text className={'w-full text-right'}>实付金额:¥{item.payPrice}</Text>
|
||||||
|
|
||||||
|
{/* 操作按钮 */}
|
||||||
|
<Space className={'btn flex justify-end'}>
|
||||||
|
{/* 待付款状态:显示取消订单和立即支付 */}
|
||||||
|
{(!item.payStatus) && item.orderStatus !== 2 && (
|
||||||
|
<Space>
|
||||||
|
<Button size={'small'} onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
void cancelOrder(item);
|
||||||
|
}}>取消订单</Button>
|
||||||
|
<Button size={'small'} type="primary" onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
void payOrder(item);
|
||||||
|
}}>立即支付</Button>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 待发货状态:显示申请退款 */}
|
||||||
|
{/*{item.payStatus && item.deliveryStatus === 10 && item.orderStatus !== 2 && item.orderStatus !== 4 && (*/}
|
||||||
|
{/* <Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* applyRefund(item);*/}
|
||||||
|
{/* }}>申请退款</Button>*/}
|
||||||
|
{/*)}*/}
|
||||||
|
|
||||||
|
{/* 待收货状态:显示查看物流和确认收货 */}
|
||||||
|
{item.deliveryStatus === 20 && item.orderStatus !== 2 && (
|
||||||
|
<Space>
|
||||||
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* viewLogistics(item);*/}
|
||||||
|
{/*}}>查看物流</Button>*/}
|
||||||
|
<Button size={'small'} type="primary" onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
confirmReceive(item);
|
||||||
|
}}>确认收货</Button>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 已完成状态:显示再次购买、评价商品、申请退款 */}
|
||||||
|
{item.orderStatus === 1 && (
|
||||||
|
<Space>
|
||||||
|
<Button size={'small'} onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
buyAgain(item);
|
||||||
|
}}>再次购买</Button>
|
||||||
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* evaluateGoods(item);*/}
|
||||||
|
{/*}}>评价商品</Button>*/}
|
||||||
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* applyRefund(item);*/}
|
||||||
|
{/*}}>申请退款</Button>*/}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 退款/售后状态:显示查看进度和撤销申请 */}
|
||||||
|
{(item.orderStatus === 4 || item.orderStatus === 7) && (
|
||||||
|
<Space>
|
||||||
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* viewProgress(item);*/}
|
||||||
|
{/*}}>查看进度</Button>*/}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 退款成功状态:显示再次购买 */}
|
||||||
|
{item.orderStatus === 6 && (
|
||||||
|
<Button size={'small'} type="primary" onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
buyAgain(item);
|
||||||
|
}}>再次购买</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
</Cell>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</InfiniteLoading>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 取消订单确认对话框 */}
|
||||||
|
<Dialog
|
||||||
|
title="确认取消"
|
||||||
|
visible={cancelDialogVisible}
|
||||||
|
confirmText="确认取消"
|
||||||
|
cancelText="我再想想"
|
||||||
|
onConfirm={handleConfirmCancel}
|
||||||
|
onCancel={handleCancelDialog}
|
||||||
|
>
|
||||||
|
确定要取消这个订单吗?
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
{/* 确认收货确认对话框 */}
|
||||||
|
<Dialog
|
||||||
|
title="确认收货"
|
||||||
|
visible={confirmReceiveDialogVisible}
|
||||||
|
confirmText="确认收货"
|
||||||
|
cancelText="我再想想"
|
||||||
|
onConfirm={handleConfirmReceive}
|
||||||
|
onCancel={handleCancelReceiveDialog}
|
||||||
|
>
|
||||||
|
确定已经收到商品了吗?确认收货后订单将完成。
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OrderList
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export default definePageConfig({
|
export default definePageConfig({
|
||||||
navigationBarTitleText: '处方',
|
navigationBarTitleText: '处方管理',
|
||||||
navigationBarTextStyle: 'black'
|
navigationBarTextStyle: 'black'
|
||||||
})
|
})
|
||||||
|
|||||||
72
src/clinic/clinicPrescription/index.scss
Normal file
72
src/clinic/clinicPrescription/index.scss
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
page {
|
||||||
|
background: linear-gradient(to bottom, #f3f3f3, #f9fafb);
|
||||||
|
background-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
.nut-input {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
border: 1px solid #e5e5e5 !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: #007bff !important;
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nut-button {
|
||||||
|
border-radius: 4px !important;
|
||||||
|
|
||||||
|
&--primary {
|
||||||
|
background: linear-gradient(135deg, #007bff, #0056b3) !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--small {
|
||||||
|
padding: 6px 12px !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabs样式优化
|
||||||
|
.nut-tabs {
|
||||||
|
.nut-tabs__titles {
|
||||||
|
background: #ffffff !important;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
|
||||||
|
|
||||||
|
.nut-tabs__titles-item {
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
color: #007bff !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nut-tabs__line {
|
||||||
|
background: #007bff !important;
|
||||||
|
height: 3px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 筛选提示样式
|
||||||
|
.filter-tip {
|
||||||
|
animation: slideDown 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,201 +1,121 @@
|
|||||||
import {useState} from "react";
|
import {useState, useCallback, useRef, useEffect} from "react";
|
||||||
import Taro, {useDidShow} from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Tag} from '@nutui/nutui-react-taro'
|
import {Space, Button, Input} from '@nutui/nutui-react-taro'
|
||||||
import {Del, Edit} from '@nutui/icons-react-taro'
|
import {View} from '@tarojs/components';
|
||||||
import {View, Text} from '@tarojs/components'
|
import OrderList from "./components/OrderList";
|
||||||
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
import {useRouter} from '@tarojs/taro'
|
||||||
import {
|
import {ShopOrderParam} from "@/api/shop/shopOrder/model";
|
||||||
pageClinicPrescription,
|
import './index.scss'
|
||||||
removeClinicPrescription
|
|
||||||
} from "@/api/clinic/clinicPrescription";
|
|
||||||
import FixedButton from "@/components/FixedButton";
|
|
||||||
import {copyText} from "@/utils/common";
|
|
||||||
|
|
||||||
const ClinicPrescriptionList = () => {
|
function ClinicPrescriptionList() {
|
||||||
const [list, setList] = useState<ClinicPrescription[]>([])
|
const {params} = useRouter();
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
const [statusBarHeight, setStatusBarHeight] = useState<number>(0) // 默认值为0
|
||||||
|
const [searchParams, setSearchParams] = useState<ShopOrderParam>({
|
||||||
|
statusFilter: params.statusFilter != undefined && params.statusFilter != '' ? parseInt(params.statusFilter) : -1
|
||||||
|
})
|
||||||
|
const [showSearch, setShowSearch] = useState(false)
|
||||||
|
const [searchKeyword, setSearchKeyword] = useState('')
|
||||||
|
const searchTimeoutRef = useRef<NodeJS.Timeout>()
|
||||||
|
|
||||||
const reload = () => {
|
const reload = async (where?: ShopOrderParam) => {
|
||||||
setLoading(true)
|
console.log(where,'where...')
|
||||||
pageClinicPrescription({
|
setSearchParams(prev => ({ ...prev, ...where }))
|
||||||
// 添加查询条件
|
|
||||||
doctorId: Taro.getStorageSync('UserId'),
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
setList(data?.list || [])
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '获取数据失败',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDel = async (item: ClinicPrescription) => {
|
// 防抖搜索函数
|
||||||
const res = await Taro.showModal({
|
const debouncedSearch = useCallback((keyword: string) => {
|
||||||
title: '确认删除',
|
if (searchTimeoutRef.current) {
|
||||||
content: `确定要删除处方编号「${item.orderNo}」吗?`,
|
clearTimeout(searchTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTimeoutRef.current = setTimeout(() => {
|
||||||
|
if (keyword.trim()) {
|
||||||
|
handleSearch({keywords: keyword.trim()});
|
||||||
|
} else {
|
||||||
|
// 如果搜索关键词为空,清除keywords参数
|
||||||
|
const newSearchParams = { ...searchParams };
|
||||||
|
delete newSearchParams.keywords;
|
||||||
|
setSearchParams(newSearchParams);
|
||||||
|
reload(newSearchParams).then();
|
||||||
|
}
|
||||||
|
}, 500); // 500ms防抖延迟
|
||||||
|
}, [searchParams]);
|
||||||
|
|
||||||
|
// 处理搜索
|
||||||
|
const handleSearch = (where: ShopOrderParam) => {
|
||||||
|
// 合并搜索参数,保留当前的statusFilter
|
||||||
|
const newSearchParams = {
|
||||||
|
...searchParams, // 保留当前的所有参数(包括statusFilter)
|
||||||
|
...where // 应用新的搜索条件
|
||||||
|
};
|
||||||
|
setSearchParams(newSearchParams)
|
||||||
|
reload(newSearchParams).then()
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
// 获取状态栏高度
|
||||||
|
Taro.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
setStatusBarHeight(res.statusBarHeight ?? 0)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
reload().then()
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (res.confirm) {
|
|
||||||
try {
|
|
||||||
await removeClinicPrescription(item.id)
|
|
||||||
Taro.showToast({
|
|
||||||
title: '删除成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
reload();
|
|
||||||
} catch (error) {
|
|
||||||
Taro.showToast({
|
|
||||||
title: '删除失败',
|
|
||||||
icon: 'error'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onEdit = (item: ClinicPrescription) => {
|
|
||||||
Taro.navigateTo({
|
|
||||||
url: `/clinic/clinicPrescription/add?id=${item.id}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDetail = (item: ClinicPrescription) => {
|
|
||||||
Taro.navigateTo({
|
|
||||||
url: `/clinic/clinicPrescription/detail?id=${item.id}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSexName = (sex?: number) => {
|
|
||||||
return sex === 0 ? '男' : sex === 1 ? '女' : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
useDidShow(() => {
|
|
||||||
reload()
|
|
||||||
});
|
|
||||||
|
|
||||||
if (list.length === 0 && !loading) {
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider>
|
<View className="bg-gray-50 min-h-screen">
|
||||||
<View className={'h-full flex flex-col justify-center items-center'} style={{
|
{/* 搜索组件 */}
|
||||||
height: 'calc(100vh - 300px)',
|
{showSearch && (
|
||||||
}}>
|
<View className="bg-white p-3 shadow-sm border-b border-gray-100">
|
||||||
<Empty
|
<View className="flex items-center">
|
||||||
style={{
|
<View className="flex-1 mr-2">
|
||||||
backgroundColor: 'transparent'
|
<Input
|
||||||
|
placeholder="搜索订单号、商品名称"
|
||||||
|
value={searchKeyword}
|
||||||
|
onChange={(value) => {
|
||||||
|
setSearchKeyword(value);
|
||||||
|
debouncedSearch(value); // 使用防抖搜索
|
||||||
|
}}
|
||||||
|
onConfirm={() => {
|
||||||
|
if (searchKeyword.trim()) {
|
||||||
|
handleSearch({keywords: searchKeyword.trim()});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
padding: '8px 12px',
|
||||||
|
border: '1px solid #e5e5e5',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#f8f9fa'
|
||||||
}}
|
}}
|
||||||
description="暂无处方数据"
|
|
||||||
/>
|
/>
|
||||||
<Space style={{marginTop: '20px'}}>
|
</View>
|
||||||
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
|
onClick={() => {
|
||||||
|
if (searchKeyword.trim()) {
|
||||||
|
handleSearch({keywords: searchKeyword.trim()});
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
新增处方
|
搜索
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</View>
|
</View>
|
||||||
</ConfigProvider>
|
</View>
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<View className="p-3">
|
|
||||||
{list.map((item) => (
|
|
||||||
<CellGroup key={item.id} className="mb-3">
|
|
||||||
<Cell
|
|
||||||
title={item.orderNo}
|
|
||||||
extra={
|
|
||||||
<Tag type={'warning'} className="font-medium">待支付</Tag>
|
|
||||||
}
|
|
||||||
onClick={() => copyText(`${item.orderNo}`)}
|
|
||||||
/>
|
|
||||||
<Cell
|
|
||||||
title={'患者名称'}
|
|
||||||
extra={
|
|
||||||
<Space>
|
|
||||||
<Text className="font-medium">{item.realName}</Text>
|
|
||||||
<Text className="font-medium">{item.age}岁</Text>
|
|
||||||
<Text className="font-medium">{getSexName(item.sex)}</Text>
|
|
||||||
</Space>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{/*<Cell*/}
|
|
||||||
{/* title="处方类型"*/}
|
|
||||||
{/* extra={*/}
|
|
||||||
{/* <Tag type="info">*/}
|
|
||||||
{/* {getPrescriptionTypeText(item.prescriptionType)}*/}
|
|
||||||
{/* </Tag>*/}
|
|
||||||
{/* }*/}
|
|
||||||
{/*/>*/}
|
|
||||||
{item.diagnosis && (
|
|
||||||
<Cell
|
|
||||||
title="诊断结果"
|
|
||||||
extra={
|
|
||||||
<Text className="text-gray-600 text-sm">
|
|
||||||
{item.diagnosis.length > 20
|
|
||||||
? `${item.diagnosis.substring(0, 20)}...`
|
|
||||||
: item.diagnosis}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<Cell
|
|
||||||
title="订单金额"
|
|
||||||
extra={
|
|
||||||
<Text className="text-red-500 font-medium">
|
|
||||||
¥{item.orderPrice || '0.00'}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Cell
|
|
||||||
title="创建时间"
|
|
||||||
extra={
|
|
||||||
<Text className="text-gray-500 text-xs">
|
|
||||||
{item.createTime}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Cell>
|
|
||||||
<Space className="w-full justify-end">
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
icon={<Edit/>}
|
|
||||||
onClick={() => onDetail(item)}
|
|
||||||
>
|
|
||||||
详情
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
icon={<Edit/>}
|
|
||||||
onClick={() => onEdit(item)}
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
icon={<Del/>}
|
|
||||||
onClick={() => onDel(item)}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
</Cell>
|
|
||||||
</CellGroup>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<FixedButton
|
{/*订单列表*/}
|
||||||
text="开处方"
|
<OrderList
|
||||||
onClick={() => Taro.navigateTo({url: '/clinic/clinicPrescription/add'})}
|
onReload={() => reload(searchParams)}
|
||||||
|
searchParams={searchParams}
|
||||||
|
showSearch={showSearch}
|
||||||
|
onSearchParamsChange={(newParams) => {
|
||||||
|
console.log('父组件接收到searchParams变化:', newParams);
|
||||||
|
setSearchParams(newParams);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</View>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ClinicPrescriptionList;
|
export default ClinicPrescriptionList;
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ function OrderList(props: OrderListProps) {
|
|||||||
// 合并搜索条件,tab的statusFilter优先级更高
|
// 合并搜索条件,tab的statusFilter优先级更高
|
||||||
const searchConditions: any = {
|
const searchConditions: any = {
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
|
type: 0,
|
||||||
userId: statusParams.userId, // 用户ID
|
userId: statusParams.userId, // 用户ID
|
||||||
...props.searchParams, // 搜索关键词等其他条件
|
...props.searchParams, // 搜索关键词等其他条件
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user