|
|
@@ -1,3 +1,4 @@
|
|
|
+
|
|
|
import { useState } from 'react';
|
|
|
import { useQuery } from '@tanstack/react-query';
|
|
|
import { useForm } from 'react-hook-form';
|
|
|
@@ -66,11 +67,142 @@ import type { InferResponseType } from 'hono/client';
|
|
|
import { UpdateOrderDto } from '@d8d/orders-module-mt/schemas';
|
|
|
|
|
|
// 类型定义
|
|
|
-type OrderResponse = InferResponseType<typeof adminOrderClient.index.$get, 200>['data'][0];
|
|
|
+type OrderResponse = InferResponseType<typeof adminOrderClient.index.$get, 200>['data'][0] & {
|
|
|
+ user?: {
|
|
|
+ id: number;
|
|
|
+ username: string;
|
|
|
+ phone: string | null;
|
|
|
+ openid?: string | null; // 添加openid字段
|
|
|
+ } | null;
|
|
|
+};
|
|
|
type UpdateRequest = any;
|
|
|
-type DeliveryRequest = any;
|
|
|
+// 发货请求类型 - 使用UpdateOrderDto的类型
|
|
|
+type DeliveryRequest = {
|
|
|
+ deliveryType: number;
|
|
|
+ deliveryCompany?: string | null;
|
|
|
+ deliveryNo?: string | null;
|
|
|
+ deliveryRemark?: string | null;
|
|
|
+ deliveryTime?: string | null;
|
|
|
+};
|
|
|
type DeliveryResponse = any;
|
|
|
|
|
|
+// 微信服务消息通知配置类型 - 参考useShareAppMessage的设计模式
|
|
|
+interface WechatServiceMessageConfig {
|
|
|
+ openid: string;
|
|
|
+ templateId: string;
|
|
|
+ page?: string;
|
|
|
+ data: Record<string, { value: string }>;
|
|
|
+ miniprogramState?: 'developer' | 'trial' | 'formal';
|
|
|
+}
|
|
|
+
|
|
|
+// 微信服务消息通知结果类型
|
|
|
+interface WechatServiceMessageResult {
|
|
|
+ success: boolean;
|
|
|
+ message: string;
|
|
|
+ data?: any;
|
|
|
+ error?: any;
|
|
|
+}
|
|
|
+
|
|
|
+// 微信服务消息通知函数 - 参考useShareAppMessage的简洁设计模式
|
|
|
+const sendWechatServiceMessage = async (config: WechatServiceMessageConfig): Promise<WechatServiceMessageResult> => {
|
|
|
+ try {
|
|
|
+ console.debug('准备发送微信服务消息:', config);
|
|
|
+
|
|
|
+ // 调用后端微信API
|
|
|
+ const response = await fetch('/api/v1/auth/send-template-message', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ openid: config.openid,
|
|
|
+ templateId: config.templateId,
|
|
|
+ data: config.data,
|
|
|
+ page: config.page || 'pages/index/index',
|
|
|
+ miniprogramState: config.miniprogramState || 'formal'
|
|
|
+ }),
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ const errorText = await response.text();
|
|
|
+ console.error('微信服务消息API调用失败:', {
|
|
|
+ status: response.status,
|
|
|
+ statusText: response.statusText,
|
|
|
+ error: errorText
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ success: false,
|
|
|
+ message: `微信服务消息发送失败: ${response.status}`,
|
|
|
+ error: errorText
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await response.json();
|
|
|
+ console.debug('微信服务消息发送成功:', result);
|
|
|
+
|
|
|
+ return {
|
|
|
+ success: true,
|
|
|
+ message: '微信服务消息发送成功',
|
|
|
+ data: result
|
|
|
+ };
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('发送微信服务消息时出错:', error);
|
|
|
+ return {
|
|
|
+ success: false,
|
|
|
+ message: '微信服务消息发送失败',
|
|
|
+ error
|
|
|
+ };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 发货成功微信通知函数 - 使用新的配置化设计
|
|
|
+const sendDeliverySuccessNotification = async (order: OrderResponse, deliveryData: DeliveryRequest): Promise<WechatServiceMessageResult> => {
|
|
|
+ // 检查是否有用户信息和openid
|
|
|
+ if (!order.user || !order.user.id) {
|
|
|
+ console.warn('订单没有用户信息,无法发送微信通知');
|
|
|
+ return { success: false, message: '订单没有用户信息,无法发送微信通知' };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查用户是否有openid(微信小程序用户)
|
|
|
+ if (!order.user.openid) {
|
|
|
+ console.warn('用户没有绑定微信小程序,无法发送微信通知', {
|
|
|
+ userId: order.user.id,
|
|
|
+ username: order.user.username
|
|
|
+ });
|
|
|
+ return { success: false, message: '用户没有绑定微信小程序,无法发送微信通知' };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建微信服务消息配置 - 参考useShareAppMessage的配置对象模式
|
|
|
+ const config: WechatServiceMessageConfig = {
|
|
|
+ openid: order.user.openid,
|
|
|
+ templateId: 'T00N0Wq3ECjksXSvPWUBgOUukl1TCE7PhxqeDnFPfso', // 发货成功通知模板ID
|
|
|
+ page: 'pages/order/detail/index', // 点击跳转到订单详情页
|
|
|
+ data: {
|
|
|
+ // 根据实际微信模板字段配置
|
|
|
+ character_string7: {
|
|
|
+ value: `订单号:${order.orderNo}`
|
|
|
+ },
|
|
|
+ date6: {
|
|
|
+ value: `${deliveryData.deliveryTime}`
|
|
|
+ },
|
|
|
+ amount9: {
|
|
|
+ value: `${order.payAmount}`
|
|
|
+ },
|
|
|
+ phrase12: {
|
|
|
+ value: `${deliveryData.deliveryType}`
|
|
|
+ },
|
|
|
+ thing4: {
|
|
|
+ value: `${deliveryData.deliveryRemark}` || '请收到货/提货后及时确认收货,2天后将自动确认收货,如有异常请及时进行交易投诉。'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ miniprogramState: 'formal'
|
|
|
+ };
|
|
|
+
|
|
|
+ // 调用微信服务消息函数
|
|
|
+ return await sendWechatServiceMessage(config);
|
|
|
+};
|
|
|
+
|
|
|
// 状态映射
|
|
|
const orderStatusMap = {
|
|
|
0: { label: '未发货', color: 'warning' },
|
|
|
@@ -197,30 +329,159 @@ export const OrderManagement = () => {
|
|
|
};
|
|
|
|
|
|
// 处理发货提交
|
|
|
+ // const handleDeliverySubmit = async (data: DeliveryRequest) => {
|
|
|
+ // if (!deliveringOrder || !deliveringOrder.id) return;
|
|
|
+
|
|
|
+ // try {
|
|
|
+ // const res = await (orderClientManager.getAdminDeliveryClient() as any)[':id']['delivery']['$post']({
|
|
|
+ // param: { id: deliveringOrder.id },
|
|
|
+ // json: data,
|
|
|
+ // });
|
|
|
+
|
|
|
+ // if (res.status === 200) {
|
|
|
+ // const result = await res.json() as DeliveryResponse;
|
|
|
+ // toast.success(result.message || '发货成功');
|
|
|
+ // setDeliveryModalOpen(false);
|
|
|
+ // refetch();
|
|
|
+ // } else {
|
|
|
+ // const error = await res.json();
|
|
|
+ // toast.error(error.message || '发货失败');
|
|
|
+ // }
|
|
|
+ // } catch (error) {
|
|
|
+ // console.error('发货失败:', error);
|
|
|
+ // toast.error('发货失败,请重试');
|
|
|
+ // }
|
|
|
+ // };
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
const handleDeliverySubmit = async (data: DeliveryRequest) => {
|
|
|
- if (!deliveringOrder || !deliveringOrder.id) return;
|
|
|
+ if (!deliveringOrder || !deliveringOrder.id) {
|
|
|
+ console.error('发货失败: deliveringOrder或id为空', { deliveringOrder });
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
try {
|
|
|
- const res = await (orderClientManager.getAdminDeliveryClient() as any)[':id']['delivery']['$post']({
|
|
|
+ // console.debug('发货请求数据:', {
|
|
|
+ // orderId: deliveringOrder.id,
|
|
|
+ // orderNo: deliveringOrder.orderNo,
|
|
|
+ // data,
|
|
|
+ // orderState: deliveringOrder.state,
|
|
|
+ // payState: deliveringOrder.payState
|
|
|
+ // });
|
|
|
+
|
|
|
+ // 使用adminOrderClient的$put接口来更新订单发货信息
|
|
|
+ // 因为adminDeliveryRoutes没有被挂载到服务器,而adminOrderRoutes已经被正确挂载
|
|
|
+
|
|
|
+ data.deliveryTime = new Date().toISOString();
|
|
|
+
|
|
|
+ const updateData = {
|
|
|
+ state: 1, // 已发货状态
|
|
|
+ deliveryType: data.deliveryType,
|
|
|
+ deliveryCompany: data.deliveryCompany || null,
|
|
|
+ deliveryNo: data.deliveryNo || null,
|
|
|
+ deliveryTime: data.deliveryTime,
|
|
|
+ deliveryRemark: data.deliveryRemark || null,
|
|
|
+ };
|
|
|
+
|
|
|
+ // console.debug('更新订单数据:', updateData);
|
|
|
+
|
|
|
+ // 调用adminOrderClient的$put接口
|
|
|
+ const res = await (orderClientManager.getAdminOrderClient() as any)[':id']['$put']({
|
|
|
param: { id: deliveringOrder.id },
|
|
|
- json: data,
|
|
|
+ json: updateData,
|
|
|
});
|
|
|
|
|
|
+ // console.debug('发货响应详情:', {
|
|
|
+ // status: res.status,
|
|
|
+ // statusText: res.statusText,
|
|
|
+ // headers: Object.fromEntries(res.headers.entries()),
|
|
|
+ // url: res.url
|
|
|
+ // });
|
|
|
+
|
|
|
if (res.status === 200) {
|
|
|
- const result = await res.json() as DeliveryResponse;
|
|
|
+ let result: DeliveryResponse;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const responseText = await res.text();
|
|
|
+ if (responseText.trim()) {
|
|
|
+ try {
|
|
|
+ result = JSON.parse(responseText) as DeliveryResponse;
|
|
|
+ } catch (parseError) {
|
|
|
+ console.error('成功响应JSON解析失败:', parseError);
|
|
|
+ result = { success: true, message: '发货成功' } as DeliveryResponse;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ result = { success: true, message: '发货成功' } as DeliveryResponse;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('处理成功响应失败:', error);
|
|
|
+ result = { success: true, message: '发货成功' } as DeliveryResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.debug('发货成功:', result);
|
|
|
toast.success(result.message || '发货成功');
|
|
|
setDeliveryModalOpen(false);
|
|
|
refetch();
|
|
|
+
|
|
|
+ // 发货成功后发送微信服务消息通知 - 使用新的配置化设计
|
|
|
+ try {
|
|
|
+ const notificationResult = await sendDeliverySuccessNotification(deliveringOrder, data);
|
|
|
+ if (notificationResult.success) {
|
|
|
+ console.debug('微信发货通知发送成功:', notificationResult);
|
|
|
+ } else {
|
|
|
+ console.warn('微信发货通知发送失败,但发货成功:', notificationResult);
|
|
|
+ // 可以在这里添加额外的处理,比如记录到日志系统
|
|
|
+ }
|
|
|
+ } catch (notificationError) {
|
|
|
+ console.error('发送微信发货通知时发生异常:', notificationError);
|
|
|
+ // 不阻止发货成功,只记录错误
|
|
|
+ }
|
|
|
} else {
|
|
|
- const error = await res.json();
|
|
|
- toast.error(error.message || '发货失败');
|
|
|
+ // 先尝试获取响应文本,避免JSON解析错误
|
|
|
+ let errorText = '';
|
|
|
+ let errorData: any = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ errorText = await res.text();
|
|
|
+ console.debug('发货失败响应文本:', errorText);
|
|
|
+
|
|
|
+ // 尝试解析为JSON
|
|
|
+ if (errorText.trim()) {
|
|
|
+ try {
|
|
|
+ errorData = JSON.parse(errorText);
|
|
|
+ } catch (parseError) {
|
|
|
+ console.warn('响应不是有效的JSON:', parseError);
|
|
|
+ errorData = { message: errorText.substring(0, 100) + '...' };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (textError) {
|
|
|
+ console.error('获取响应文本失败:', textError);
|
|
|
+ errorData = { message: `请求失败,状态码: ${res.status}` };
|
|
|
+ }
|
|
|
+
|
|
|
+ console.error('发货失败响应:', {
|
|
|
+ status: res.status,
|
|
|
+ statusText: res.statusText,
|
|
|
+ errorData,
|
|
|
+ errorText: errorText.substring(0, 200),
|
|
|
+ orderId: deliveringOrder.id
|
|
|
+ });
|
|
|
+
|
|
|
+ // 显示错误消息
|
|
|
+ const errorMessage = errorData?.message ||
|
|
|
+ errorData?.error?.message ||
|
|
|
+ res.statusText ||
|
|
|
+ `发货失败 (${res.status})`;
|
|
|
+ toast.error(errorMessage);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- console.error('发货失败:', error);
|
|
|
+ console.error('发货请求异常:', error);
|
|
|
toast.error('发货失败,请重试');
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+
|
|
|
// 处理更新订单
|
|
|
const handleUpdateSubmit = async (data: UpdateRequest) => {
|
|
|
if (!editingOrder || !editingOrder.id) return;
|