From 6ba0484f336ab7f914c50e8e6055a2df29a72e0d Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 6 May 2025 22:14:10 +0800 Subject: [PATCH 01/19] =?UTF-8?q?perf:=20vben5=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codegen/vue3_vben5_antd/general/views/index.vue.vm | 9 ++++----- .../general/views/modules/list_sub_erp.vue.vm | 4 ++-- .../codegen/vue3_vben5_antd/schema/views/data.ts.vm | 4 ++-- .../codegen/vue3_vben5_antd/schema/views/form.vue.vm | 5 +---- .../codegen/vue3_vben5_antd/schema/views/index.vue.vm | 9 +++------ .../schema/views/modules/form_sub_erp.vue.vm | 5 +---- .../schema/views/modules/list_sub_erp.vue.vm | 7 ++----- 7 files changed, 15 insertions(+), 28 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm index c7f4822686..0a39bb6aa0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm @@ -3,7 +3,7 @@ import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleCl import type { VxeTableInstance } from 'vxe-table'; import { Page, useVbenModal } from '@vben/common-ui'; -import { cloneDeep, formatDateTime } from '@vben/utils'; +import { cloneDeep, formatDateTime, getRangePickerDefaultProps } from '@vben/utils'; import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue'; import { DictTag } from '#/components/dict-tag'; import { DICT_TYPE, getDictOptions } from '#/utils/dict'; @@ -12,7 +12,6 @@ import { Download, Plus, RefreshCw, Search } from '@vben/icons'; import { ContentWrap } from "#/components/content-wrap"; import { VxeColumn, VxeTable } from 'vxe-table'; import { TableToolbar } from '#/components/table-toolbar'; -import { getRangePickerDefaultProps } from '#/utils/date'; ## 特殊:主子表专属逻辑 #if ( $table.templateType == 11 || $table.templateType == 12 ) @@ -31,7 +30,7 @@ import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClas #else## 标准表接口 import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; #end -import { downloadByData } from '#/utils/download'; +import { downloadFileFromBlobPart } from '@vben/utils'; #if ($table.templateType == 12 || $table.templateType == 11) ## 内嵌和erp情况 /** 子表的列表 */ @@ -162,7 +161,7 @@ async function onExport() { try { exportLoading.value = true; const data = await export${simpleClassName}(queryParams); - downloadByData(data, '${table.classComment}.xls'); + downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data }); }finally { exportLoading.value = false; } @@ -281,7 +280,7 @@ onMounted(async () => { - + \ No newline at end of file + diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm index f4034cbe5c..4357944ada 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm @@ -5,10 +5,10 @@ import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleCl import { z } from '#/adapter/form'; #if(${table.templateType} == 2)## 树表需要导入这些 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; -import { handleTree } from '#/utils/tree'; +import { handleTree } from '@vben/utils'; #end import { DICT_TYPE, getDictOptions } from '#/utils/dict'; -import { getRangePickerDefaultProps } from '#/utils/date'; +import { getRangePickerDefaultProps } from '@vben/utils'; import { useAccess } from '@vben/access'; const { hasAccessByCodes } = useAccess(); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm index 227b8c2982..c4e0eecfb4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm @@ -102,10 +102,7 @@ const [Modal, modalApi] = useVbenModal({ // 关闭并提示 await modalApi.close(); emit('success'); - message.success({ - content: $t('ui.actionMessage.operationSuccess'), - key: 'action_process_msg', - }); + message.success( $t('ui.actionMessage.operationSuccess') ); } finally { modalApi.unlock(); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm index bf27df8052..9b3fbde62f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/index.vue.vm @@ -24,7 +24,7 @@ import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClas #else## 标准表接口 import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; #end -import { downloadByData } from '#/utils/download'; +import { downloadFileFromBlobPart } from '@vben/utils'; import { useGridColumns, useGridFormSchema } from './data'; @@ -85,10 +85,7 @@ async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) { }); try { await delete${simpleClassName}(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.id]), - key: 'action_process_msg', - }); + message.success( $t('ui.actionMessage.deleteSuccess', [row.id]) ); onRefresh(); } catch { hideLoading(); @@ -98,7 +95,7 @@ async function onDelete(row: ${simpleClassName}Api.${simpleClassName}) { /** 导出表格 */ async function onExport() { const data = await export${simpleClassName}(await gridApi.formApi.getValues()); - downloadByData(data, '${table.classComment}.xls'); + downloadFileFromBlobPart({ fileName: '${table.classComment}.xls', source: data }); } /** 表格操作按钮的回调函数 */ diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_erp.vue.vm index e114b7daea..739849631c 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/form_sub_erp.vue.vm @@ -52,10 +52,7 @@ // 关闭并提示 await modalApi.close(); emit('success'); - message.success({ - content: $t('ui.actionMessage.operationSuccess'), - key: 'action_process_msg', - }); + message.success( $t('ui.actionMessage.operationSuccess') ); } finally { modalApi.unlock(); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm index b7990a5de2..616be9f299 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/modules/list_sub_erp.vue.vm @@ -65,10 +65,7 @@ async function onDelete(row: ${simpleClassName}Api.${subSimpleClassName}) { }); try { await delete${subSimpleClassName}(row.id as number); - message.success({ - content: $t('ui.actionMessage.deleteSuccess', [row.id]), - key: 'action_process_msg', - }); + message.success( $t('ui.actionMessage.deleteSuccess', [row.id]) ); onRefresh(); } catch { hideLoading(); @@ -181,4 +178,4 @@ const onRefresh = async ()=> { #else #end - \ No newline at end of file + From 5327d3a494cb7b6b6c03d42ac71dbec5c27cf61d Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 6 May 2025 23:26:44 +0800 Subject: [PATCH 02/19] =?UTF-8?q?perf:=20vben5=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codegen/vue3_vben5_antd/general/views/form.vue.vm | 2 +- .../codegen/vue3_vben5_antd/general/views/index.vue.vm | 4 ++-- .../general/views/modules/form_sub_erp.vue.vm | 2 +- .../general/views/modules/form_sub_normal.vue.vm | 2 +- .../general/views/modules/list_sub_erp.vue.vm | 5 ++--- .../codegen/vue3_vben5_antd/schema/views/data.ts.vm | 3 +-- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm index 187f66c144..90c0a6e9c5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/form.vue.vm @@ -6,7 +6,7 @@ import { useVbenModal } from '@vben/common-ui'; import { Tinymce as RichTextarea } from '#/components/tinymce'; import { ImageUpload, FileUpload } from "#/components/upload"; import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue'; -import { DICT_TYPE, getDictOptions } from '#/utils/dict'; +import { DICT_TYPE, getDictOptions } from '#/utils'; #if($table.templateType == 2)## 树表需要导入这些 import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; import { handleTree } from '@vben/utils' diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm index 0a39bb6aa0..7f50460847 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/index.vue.vm @@ -3,10 +3,10 @@ import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleCl import type { VxeTableInstance } from 'vxe-table'; import { Page, useVbenModal } from '@vben/common-ui'; -import { cloneDeep, formatDateTime, getRangePickerDefaultProps } from '@vben/utils'; +import { cloneDeep, formatDateTime } from '@vben/utils'; import { Button, message,Tabs,Pagination,Form,RangePicker,DatePicker,Select,Input } from 'ant-design-vue'; import { DictTag } from '#/components/dict-tag'; -import { DICT_TYPE, getDictOptions } from '#/utils/dict'; +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; import ${simpleClassName}Form from './modules/form.vue'; import { Download, Plus, RefreshCw, Search } from '@vben/icons'; import { ContentWrap } from "#/components/content-wrap"; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm index 77b9d11dd2..6517e31bf2 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_erp.vue.vm @@ -10,7 +10,7 @@ import { Tinymce as RichTextarea } from '#/components/tinymce'; import { ImageUpload, FileUpload } from "#/components/upload"; import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue'; - import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + import { DICT_TYPE, getDictOptions } from '#/utils'; import { computed, ref } from 'vue'; import { $t } from '#/locales'; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm index c838f95320..914154ff52 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/form_sub_normal.vue.vm @@ -10,7 +10,7 @@ import { message, Tabs, Form, Input, Textarea,Button, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker } from 'ant-design-vue'; import { computed, ref, h, onMounted,watch,nextTick } from 'vue'; import { $t } from '#/locales'; - import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + import { DICT_TYPE, getDictOptions } from '#/utils'; #if ($subTable.subJoinMany) ## 一对多 import type { VxeTableInstance } from 'vxe-table'; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm index 1a5b2f1ae9..52e25d3989 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/general/views/modules/list_sub_erp.vue.vm @@ -10,7 +10,7 @@ import type { VxeTableInstance } from 'vxe-table'; import { DictTag } from '#/components/dict-tag'; - import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + import { DICT_TYPE, getDictOptions } from '#/utils'; import { VxeColumn, VxeTable } from 'vxe-table'; import { reactive,ref, h, nextTick,watch,onMounted } from 'vue'; import { cloneDeep, formatDateTime } from '@vben/utils'; @@ -22,11 +22,10 @@ import { Tinymce as RichTextarea } from '#/components/tinymce'; import { ImageUpload, FileUpload } from "#/components/upload"; import { message,Button, Tabs,Pagination, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox,RangePicker, DatePicker, TreeSelect } from 'ant-design-vue'; - import { DICT_TYPE, getDictOptions } from '#/utils/dict'; + import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; import { Plus } from '@vben/icons'; import { $t } from '#/locales'; import { TableToolbar } from '#/components/table-toolbar'; - import { getRangePickerDefaultProps } from '@vben/utils'; #end #if ($table.templateType == 11) ## erp diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm index 4357944ada..d7a90dcc20 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm @@ -7,8 +7,7 @@ import { z } from '#/adapter/form'; import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}'; import { handleTree } from '@vben/utils'; #end -import { DICT_TYPE, getDictOptions } from '#/utils/dict'; -import { getRangePickerDefaultProps } from '@vben/utils'; +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; import { useAccess } from '@vben/access'; const { hasAccessByCodes } = useAccess(); From ffee1895898b724476d8f545a609c41acace645b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 7 May 2025 09:21:29 +0800 Subject: [PATCH 03/19] =?UTF-8?q?reactor=EF=BC=9A=E7=A7=BB=E9=99=A4=20PayC?= =?UTF-8?q?lient=20=E8=8E=B7=E5=8F=96=E8=BD=AC=E8=B4=A6=E6=97=B6=E7=9A=84?= =?UTF-8?q?=20type=20=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=E4=BC=9A=E5=8C=BA=E5=88=86=EF=BC=8C?= =?UTF-8?q?=E5=90=8E=E7=BB=AD=E9=80=9A=E8=BF=87=20channelExtras=20?= =?UTF-8?q?=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../transfer/PayDemoTransferCreateReqVO.java | 1 - .../framework/pay/core/WalletPayClient.java | 5 +- .../transfer/PayTransferServiceImpl.java | 4 +- .../framework/pay/core/client/PayClient.java | 4 +- .../transfer/PayTransferUnifiedReqDTO.java | 20 ++--- .../core/client/impl/AbstractPayClient.java | 27 ++---- .../impl/alipay/AbstractAlipayPayClient.java | 90 ++++++++----------- .../core/client/impl/mock/MockPayClient.java | 3 +- .../impl/weixin/AbstractWxPayClient.java | 3 +- .../enums/transfer/PayTransferTypeEnum.java | 1 + 10 files changed, 53 insertions(+), 105 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java index 73288372b5..8fd2a65098 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java @@ -44,7 +44,6 @@ public class PayDemoTransferCreateReqVO { @NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class}) private String openid; - // ========== 转账到银行卡和钱包相关字段 待补充 ========== public void validate(Validator validator) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java index 2dd5893fd8..d9a6511aae 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java @@ -14,12 +14,11 @@ import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; -import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; @@ -188,7 +187,7 @@ public class WalletPayClient extends AbstractPayClient { } @Override - protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) { + protected PayTransferRespDTO doGetTransfer(String outTradeNo) { throw new UnsupportedOperationException("待实现"); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 1825b3a45e..d4a7c9d639 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; @@ -283,8 +282,7 @@ public class PayTransferServiceImpl implements PayTransferService { log.error("[syncTransfer][渠道编号({}) 找不到对应的支付客户端]", transfer.getChannelId()); return false; } - PayTransferRespDTO resp = payClient.getTransfer(transfer.getNo(), - PayTransferTypeEnum.typeOf(transfer.getType())); + PayTransferRespDTO resp = payClient.getTransfer(transfer.getNo()); // 2. 回调转账结果 notifyTransfer(transfer.getChannelId(), resp); diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index 64a56a5ca3..a7abb20e09 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import java.util.Map; @@ -95,10 +94,9 @@ public interface PayClient { * 获得转账订单信息 * * @param outTradeNo 外部订单号 - * @param type 转账类型 * @return 转账信息 */ - PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type); + PayTransferRespDTO getTransfer(String outTradeNo); /** * 解析 transfer 回调数据 diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index 509223f608..c1e6077b17 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -1,19 +1,17 @@ package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.URL; import java.util.Map; -import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.*; +import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.Alipay; +import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.WxPay; /** * 统一转账 Request DTO @@ -23,15 +21,6 @@ import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferType @Data public class PayTransferUnifiedReqDTO { - /** - * 转账类型 - * - * 关联 {@link PayTransferTypeEnum#getType()} - */ - @NotNull(message = "转账类型不能为空") - @InEnum(PayTransferTypeEnum.class) - private Integer type; - /** * 用户 IP */ @@ -55,6 +44,7 @@ public class PayTransferUnifiedReqDTO { @Length(max = 128, message = "转账标题不能超过 128") private String subject; + // TODO @芋艿:userName、alipayLogonId、openid =》channelExtras;另外:validatePayTransferReqDTO 去掉; /** * 收款人姓名 */ diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index a478d4e629..52d0a2f4ca 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -188,7 +188,6 @@ public abstract class AbstractPayClient implemen @Override public final PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { - validatePayTransferReqDTO(reqDTO); PayTransferRespDTO resp; try { resp = doUnifiedTransfer(reqDTO); @@ -202,22 +201,6 @@ public abstract class AbstractPayClient implemen } return resp; } - private void validatePayTransferReqDTO(PayTransferUnifiedReqDTO reqDTO) { - PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType()); - switch (transferType) { - case ALIPAY_BALANCE: { - ValidationUtils.validate(reqDTO, PayTransferTypeEnum.Alipay.class); - break; - } - case WX_BALANCE: { - ValidationUtils.validate(reqDTO, PayTransferTypeEnum.WxPay.class); - break; - } - default: { - throw exception(NOT_IMPLEMENTED); - } - } - } @Override public final PayTransferRespDTO parseTransferNotify(Map params, String body, Map headers) { @@ -236,14 +219,14 @@ public abstract class AbstractPayClient implemen throws Throwable; @Override - public final PayTransferRespDTO getTransfer(String outTradeNo, PayTransferTypeEnum type) { + public final PayTransferRespDTO getTransfer(String outTradeNo) { try { - return doGetTransfer(outTradeNo, type); + return doGetTransfer(outTradeNo); } catch (ServiceException ex) { // 业务异常,都是实现类已经翻译,所以直接抛出即可 throw ex; } catch (Throwable ex) { - log.error("[getTransfer][客户端({}) outTradeNo({}) type({}) 查询转账单异常]", - getId(), outTradeNo, type, ex); + log.error("[getTransfer][客户端({}) outTradeNo({}) 查询转账单异常]", + getId(), outTradeNo, ex); throw buildPayException(ex); } } @@ -251,7 +234,7 @@ public abstract class AbstractPayClient implemen protected abstract PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws Throwable; - protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) + protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo) throws Throwable; // ========== 各种工具方法 ========== diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index b0f728eecf..a16516fdb2 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -16,7 +17,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDT import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConfig; import com.alipay.api.AlipayResponse; @@ -40,8 +40,7 @@ import java.util.Objects; import java.util.function.Supplier; import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.ERROR_CONFIGURATION; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE; import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY; @@ -236,11 +235,12 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient { } @Override - protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferTypeEnum type) { + protected PayTransferRespDTO doGetTransfer(String outTradeNo) { throw new UnsupportedOperationException("待实现"); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index e681cfbea4..b53f88c2eb 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -17,7 +17,6 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifie import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPartnerNotifyV3Result; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import com.github.binarywang.wxpay.bean.notify.*; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; @@ -489,7 +488,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Wed, 7 May 2025 23:37:24 +0800 Subject: [PATCH 04/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E5=AE=8C=E5=96=84=E6=94=AF=E4=BB=98=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E7=A4=BA=E4=BE=8B=EF=BC=8C=E4=BB=A5=E5=8F=8A=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E5=8A=9F=E8=83=BD=EF=BC=88=E6=94=AF=E4=BB=98=E5=AE=9D?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrokerageWithdrawServiceImpl.java | 8 +- .../transfer/dto/PayTransferCreateReqDTO.java | 32 ++-- .../module/pay/enums/ErrorCodeConstants.java | 9 +- .../enums/transfer/PayTransferStatusEnum.java | 25 ++- .../enums/transfer/PayTransferTypeEnum.java | 44 ------ .../admin/demo/PayDemoOrderController.java | 9 +- .../admin/demo/PayDemoTransferController.http | 13 ++ .../admin/demo/PayDemoTransferController.java | 13 +- .../transfer/PayDemoTransferCreateReqVO.java | 61 ++------ .../admin/transfer/PayTransferController.java | 32 ++-- .../transfer/vo/PayTransferCreateReqVO.java | 95 ------------ .../transfer/vo/PayTransferPageReqVO.java | 3 - .../pay/convert/demo/PayDemoOrderConvert.java | 26 ---- .../convert/demo/PayDemoTransferConvert.java | 21 --- .../convert/transfer/PayTransferConvert.java | 31 ---- .../dataobject/demo/PayDemoTransferDO.java | 45 +++--- .../dataobject/transfer/PayTransferDO.java | 28 +--- .../dal/mysql/transfer/PayTransferMapper.java | 17 ++- .../service/demo/PayDemoOrderServiceImpl.java | 1 - .../demo/PayDemoTransferServiceImpl.java | 49 +++--- .../service/transfer/PayTransferService.java | 13 -- .../transfer/PayTransferServiceImpl.java | 144 ++++++++---------- .../dto/transfer/PayTransferRespDTO.java | 6 +- .../transfer/PayTransferUnifiedReqDTO.java | 29 ++-- .../core/client/impl/AbstractPayClient.java | 3 - .../impl/alipay/AbstractAlipayPayClient.java | 23 +-- .../impl/weixin/AbstractWxPayClient.java | 6 +- .../client/impl/weixin/WxPubPayClient.java | 5 - .../transfer/PayTransferStatusRespEnum.java | 20 +-- .../enums/transfer/PayTransferTypeEnum.java | 45 ------ 30 files changed, 251 insertions(+), 605 deletions(-) delete mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferTypeEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferCreateReqVO.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoTransferConvert.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java delete mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 2eef855b6e..b05f558a54 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; -import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; +//import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; @@ -140,11 +140,11 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 1.2 构建请求 PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()) - .setChannelCode("wx_lite").setType(PayTransferTypeEnum.WX_BALANCE.getType()) + .setChannelCode("wx_lite") // TODO @芋艿:【转账】这里要处理下; .setMerchantTransferId(withdraw.getId().toString()) .setPrice(withdraw.getPrice()) .setSubject("佣金提现") - .setOpenid(socialUser.getOpenid()).setUserIp(getClientIP()); + .setUserAccount(socialUser.getOpenid()).setUserIp(getClientIP()); // 2. 发起请求 return payTransferApi.createTransfer(payTransferCreateReqDTO); } @@ -226,7 +226,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) { withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()); // TODO @luchi:发送站内信 - } else if (PayTransferStatusEnum.isPendingStatus(transfer.getStatus())) { + } else if (PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { // TODO @luchi:这里,是不是不用更新哈? withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()); } else { diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index 05159671b9..2d556ceebb 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -1,9 +1,6 @@ package cn.iocoder.yudao.module.pay.api.transfer.dto; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -24,6 +21,9 @@ public class PayTransferCreateReqDTO { @NotNull(message = "应用标识不能为空") private String appKey; + /** + * 转账渠道 + */ @NotEmpty(message = "转账渠道不能为空") private String channelCode; @@ -32,17 +32,12 @@ public class PayTransferCreateReqDTO { */ private Map channelExtras; + /** + * 用户 IP + */ @NotEmpty(message = "用户 IP 不能为空") private String userIp; - /** - * 类型 - */ - @NotNull(message = "转账类型不能为空") - @InEnum(PayTransferTypeEnum.class) - private Integer type; - - /** * 商户转账单编号 */ @@ -62,16 +57,17 @@ public class PayTransferCreateReqDTO { @NotEmpty(message = "转账标题不能为空") private String subject; + /** + * 收款人账号 + * + * 微信场景下:openid + * 支付宝场景下:支付宝账号 + */ + @NotEmpty(message = "收款人账号不能为空") + private String userAccount; /** * 收款人姓名 */ - @NotBlank(message = "收款人姓名不能为空", groups = {PayTransferTypeEnum.Alipay.class}) private String userName; - @NotBlank(message = "支付宝登录号不能为空", groups = {PayTransferTypeEnum.Alipay.class}) - private String alipayLogonId; - - // ========== 微信转账相关字段 ========== - @NotBlank(message = "微信 openId 不能为空", groups = {PayTransferTypeEnum.WxPay.class}) - private String openid; } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 131698e4a0..ec983d168e 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -65,13 +65,12 @@ public interface ErrorCodeConstants { ErrorCode WALLET_RECHARGE_PACKAGE_NAME_EXISTS = new ErrorCode(1_007_008_013, "钱包充值套餐名称已存在"); // ========== 转账模块 1-007-009-000 ========== - ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); ErrorCode PAY_TRANSFER_NOT_FOUND = new ErrorCode(1_007_009_001, "转账单不存在"); - ErrorCode PAY_SAME_MERCHANT_TRANSFER_TYPE_NOT_MATCH = new ErrorCode(1_007_009_002, "两次相同转账请求的类型不匹配"); - ErrorCode PAY_SAME_MERCHANT_TRANSFER_PRICE_NOT_MATCH = new ErrorCode(1_007_009_003, "两次相同转账请求的金额不匹配"); - ErrorCode PAY_MERCHANT_TRANSFER_EXISTS = new ErrorCode(1_007_009_004, "该笔业务的转账已经发起,请查询转账订单相关状态"); + ErrorCode PAY_TRANSFER_CREATE_CHANNEL_NOT_MATCH = new ErrorCode(1_007_009_002, "转账发起失败,原因:两次相同转账请求的类型不匹配"); + ErrorCode PAY_TRANSFER_CREATE_PRICE_NOT_MATCH = new ErrorCode(1_007_009_003, "转账发起失败,原因:两次相同转账请求的金额不匹配"); + ErrorCode PAY_TRANSFER_CREATE_MERCHANT_EXISTS = new ErrorCode(1_007_009_004, "转账发起失败,原因:该笔业务的转账已经发起,请查询转账订单相关状态"); ErrorCode PAY_TRANSFER_STATUS_IS_NOT_WAITING = new ErrorCode(1_007_009_005, "转账单不处于待转账"); - ErrorCode PAY_TRANSFER_STATUS_IS_NOT_PENDING = new ErrorCode(1_007_009_006, "转账单不处于待转账或转账中"); + ErrorCode PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING = new ErrorCode(1_007_009_006, "转账单不处于待转账或转账中"); // ========== 示例订单 1-007-900-000 ========== ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1_007_900_000, "示例订单不存在"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java index 6f2f27c753..27d37c7bd3 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java @@ -6,6 +6,8 @@ import lombok.Getter; import java.util.Objects; /** + * 渠道的转账状态枚举 + * * @author jason */ @Getter @@ -13,16 +15,9 @@ import java.util.Objects; public enum PayTransferStatusEnum { WAITING(0, "等待转账"), - /** - * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现 - */ - IN_PROGRESS(10, "转账进行中"), - - SUCCESS(20, "转账成功"), - /** - * 转账关闭 (失败,或者其它情况) // TODO 改成 转账失败状态 - */ - CLOSED(30, "转账关闭"); + PROCESSING(5, "转账进行中"), + SUCCESS(10, "转账成功"), + CLOSED(20, "转账关闭"); /** * 状态 @@ -44,16 +39,18 @@ public enum PayTransferStatusEnum { public static boolean isWaiting(Integer status) { return Objects.equals(status, WAITING.getStatus()); } - public static boolean isInProgress(Integer status) { - return Objects.equals(status, IN_PROGRESS.getStatus()); + + public static boolean isProgressing(Integer status) { + return Objects.equals(status, PROCESSING.getStatus()); } /** * 是否处于待转账或者转账中的状态 + * * @param status 状态 */ - public static boolean isPendingStatus(Integer status) { - return Objects.equals(status, WAITING.getStatus()) || Objects.equals(status, IN_PROGRESS.getStatus()); + public static boolean isWaitingOrProcessing(Integer status) { + return isWaiting(status) || isProgressing(status); } } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferTypeEnum.java deleted file mode 100644 index 66fa6f38f9..0000000000 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferTypeEnum.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.pay.enums.transfer; - -import cn.hutool.core.util.ArrayUtil; -import cn.iocoder.yudao.framework.common.core.ArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 转账类型枚举 - * - * @author jason - */ -@AllArgsConstructor -@Getter -public enum PayTransferTypeEnum implements ArrayValuable { - - ALIPAY_BALANCE(1, "支付宝余额"), - WX_BALANCE(2, "微信余额"), - BANK_CARD(3, "银行卡"), - WALLET_BALANCE(4, "钱包余额"); - - public interface WxPay { - } - - public interface Alipay { - } - - private final Integer type; - private final String name; - - public static final Integer[] ARRAYS = Arrays.stream(values()).map(PayTransferTypeEnum::getType).toArray(Integer[]::new); - - @Override - public Integer[] array() { - return ARRAYS; - } - - public static PayTransferTypeEnum typeOf(Integer type) { - return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); - } - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 538fdbc227..8eebc223b6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -3,22 +3,21 @@ package cn.iocoder.yudao.module.pay.controller.admin.demo; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.order.PayDemoOrderCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.order.PayDemoOrderRespVO; -import cn.iocoder.yudao.module.pay.convert.demo.PayDemoOrderConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; import cn.iocoder.yudao.module.pay.service.demo.PayDemoOrderService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - import jakarta.annotation.Resource; import jakarta.annotation.security.PermitAll; import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @@ -43,7 +42,7 @@ public class PayDemoOrderController { @Operation(summary = "获得示例订单分页") public CommonResult> getDemoOrderPage(@Valid PageParam pageVO) { PageResult pageResult = payDemoOrderService.getDemoOrderPage(pageVO); - return success(PayDemoOrderConvert.INSTANCE.convertPage(pageResult)); + return success(BeanUtils.toBean(pageResult, PayDemoOrderRespVO.class)); } @PostMapping("/update-paid") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http new file mode 100644 index 0000000000..08f7c24a60 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http @@ -0,0 +1,13 @@ +### 请求 /pay/pay/demo-order 接口 => 成功 +POST {{baseUrl}}/pay/demo-transfer/create +Authorization: Bearer {{token}} +Content-Type: application/json +tenant-id: {{adminTenantId}} + +{ + "channelCode": "alipay_pc", + "subject": "测试转账", + "price": 10, + "userAccount": "oespxk7368@sandbox.com", + "userName": "oespxk7368" +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java index 3d399181b6..be31ae51a5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java @@ -3,20 +3,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.demo; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferRespVO; -import cn.iocoder.yudao.module.pay.convert.demo.PayDemoTransferConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; import cn.iocoder.yudao.module.pay.service.demo.PayDemoTransferService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - import jakarta.annotation.Resource; import jakarta.annotation.security.PermitAll; import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -31,14 +30,15 @@ public class PayDemoTransferController { @PostMapping("/create") @Operation(summary = "创建示例转账订单") public CommonResult createDemoTransfer(@Valid @RequestBody PayDemoTransferCreateReqVO createReqVO) { - return success(demoTransferService.createDemoTransfer(createReqVO)); + Long id = demoTransferService.createDemoTransfer(createReqVO); + return success(id); } @GetMapping("/page") @Operation(summary = "获得示例转账订单分页") public CommonResult> getDemoTransferPage(@Valid PageParam pageVO) { PageResult pageResult = demoTransferService.getDemoTransferPage(pageVO); - return success(PayDemoTransferConvert.INSTANCE.convertPage(pageResult)); + return success(BeanUtils.toBean(pageResult, PayDemoTransferRespVO.class)); } @PostMapping("/update-status") @@ -49,4 +49,5 @@ public class PayDemoTransferController { notifyReqDTO.getPayTransferId()); return success(true); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java index 8fd2a65098..f749dff507 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java @@ -1,66 +1,35 @@ package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer; -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.Validator; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.Data; -import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum.*; - -/** - * @author jason - */ @Schema(description = "管理后台 - 示例转账单创建 Request VO") @Data public class PayDemoTransferCreateReqVO { - @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "转账类型不能为空") - @InEnum(PayTransferTypeEnum.class) - private Integer type; + @Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_lite") + @NotEmpty(message = "转账渠道不能为空") + private String channelCode; - @Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿是一种菜") + @NotEmpty(message = "转账标题不能为空") + private String subject; + + @Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") @NotNull(message = "转账金额不能为空") @Min(value = 1, message = "转账金额必须大于零") private Integer price; + @Schema(description = "收款人账号", requiredMode= Schema.RequiredMode.REQUIRED, example = "test1") + @NotBlank(message = "收款人账号不能为空") + private String userAccount; + @Schema(description = "收款人姓名", example = "test1") - @NotBlank(message = "收款人姓名不能为空", groups = {Alipay.class}) + @NotBlank(message = "收款人姓名不能为空") private String userName; - // ========== 支付宝转账相关字段 ========== - @Schema(description = "支付宝登录号,支持邮箱和手机号格式", example = "test1@@sandbox.com") - @NotBlank(message = "支付宝登录号不能为空", groups = {Alipay.class}) - private String alipayLogonId; - - // ========== 微信转账相关字段 ========== - @Schema(description = "微信 openId", example = "oLefc4g5Gxx") - @NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class}) - private String openid; - - // ========== 转账到银行卡和钱包相关字段 待补充 ========== - - public void validate(Validator validator) { - PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(type); - switch (transferType) { - case ALIPAY_BALANCE: { - ValidationUtils.validate(validator, this, Alipay.class); - break; - } - case WX_BALANCE: { - ValidationUtils.validate(validator, this, WxPay.class); - break; - } - default: { - throw new UnsupportedOperationException("待实现"); - } - } - } - } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java index 72593c9630..add9064974 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java @@ -2,21 +2,24 @@ package cn.iocoder.yudao.module.pay.controller.admin.transfer; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.*; -import cn.iocoder.yudao.module.pay.convert.transfer.PayTransferConvert; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @Tag(name = "管理后台 - 转账单") @RestController @@ -27,26 +30,21 @@ public class PayTransferController { @Resource private PayTransferService payTransferService; - @PostMapping("/create") - @Operation(summary = "创建转账单,发起转账") - @PreAuthorize("@ss.hasPermission('pay:transfer:create')") - public CommonResult createPayTransfer(@Valid @RequestBody PayTransferCreateReqVO reqVO) { - PayTransferDO payTransfer = payTransferService.createTransfer(reqVO, getClientIP()); - return success(new PayTransferCreateRespVO().setId(payTransfer.getId()).setStatus(payTransfer.getStatus())); - } - @GetMapping("/get") @Operation(summary = "获得转账订单") @PreAuthorize("@ss.hasPermission('pay:transfer:query')") public CommonResult getTransfer(@RequestParam("id") Long id) { - return success(PayTransferConvert.INSTANCE.convert(payTransferService.getTransfer(id))); + PayTransferDO transfer = payTransferService.getTransfer(id); + return success(BeanUtils.toBean(transfer, PayTransferRespVO.class)); } + // TODO @芋艿:get 和 page 的返回,是不是统一融合 @GetMapping("/page") @Operation(summary = "获得转账订单分页") @PreAuthorize("@ss.hasPermission('pay:transfer:query')") public CommonResult> getTransferPage(@Valid PayTransferPageReqVO pageVO) { PageResult pageResult = payTransferService.getTransferPage(pageVO); - return success(PayTransferConvert.INSTANCE.convertPage(pageResult)); + return success(BeanUtils.toBean(pageResult, PayTransferPageItemRespVO.class)); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferCreateReqVO.java deleted file mode 100644 index bda44cff65..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferCreateReqVO.java +++ /dev/null @@ -1,95 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.transfer.vo; - -import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; -import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.Validator; -import jakarta.validation.constraints.*; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum.*; - -@Schema(description = "管理后台 - 发起转账 Request VO") -@Data -public class PayTransferCreateReqVO { - - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "应用编号不能为空") - private Long appId; - - @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "商户转账单编号不能为空") - private String merchantTransferId; - - @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "转账类型不能为空") - @InEnum(PayTransferTypeEnum.class) - private Integer type; - - @Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc") - @NotEmpty(message = "转账渠道不能为空") - private String channelCode; - - @Min(value = 1, message = "转账金额必须大于零") - @NotNull(message = "转账金额不能为空") - private Integer price; - - @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "示例转账") - @NotEmpty(message = "转账标题不能为空") - private String subject; - - @Schema(description = "收款人姓名", example = "test1") - @NotBlank(message = "收款人姓名不能为空", groups = {Alipay.class}) - private String userName; - - @Schema(description = "支付宝登录号", example = "test1@sandbox.com") - @NotBlank(message = "支付宝登录号不能为空", groups = {Alipay.class}) - private String alipayLogonId; - - @Schema(description = "微信 openId", example = "oLefc4g5Gxx") - @NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class}) - private String openid; - - @Schema(description = "转账渠道的额外参数") - private Map channelExtras; - - public void validate(Validator validator) { - PayTransferTypeEnum transferType = typeOf(type); - switch (transferType) { - case ALIPAY_BALANCE: { - ValidationUtils.validate(validator, this, Alipay.class); - break; - } - case WX_BALANCE: { - ValidationUtils.validate(validator, this, WxPay.class); - break; - } - default: { - throw new UnsupportedOperationException("待实现"); - } - } - } - - @AssertTrue(message = "转账类型和转账渠道不匹配") - public boolean isValidChannelCode() { - PayTransferTypeEnum transferType = typeOf(type); - switch (transferType) { - case ALIPAY_BALANCE: { - return PayChannelEnum.isAlipay(channelCode); - } - case WX_BALANCE: - case BANK_CARD: - case WALLET_BALANCE: { - throw exception(NOT_IMPLEMENTED); - } - } - return Boolean.FALSE; - } - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java index 88cda1b599..eeb9a0285b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java @@ -26,9 +26,6 @@ public class PayTransferPageReqVO extends PageParam { @Schema(description = "商户转账单编号", example = "17481") private String merchantTransferId; - @Schema(description = "类型", example = "2") - private Integer type; - @Schema(description = "转账状态", example = "2") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java deleted file mode 100644 index 8fca997919..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.pay.convert.demo; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.order.PayDemoOrderCreateReqVO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.order.PayDemoOrderRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 示例订单 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface PayDemoOrderConvert { - - PayDemoOrderConvert INSTANCE = Mappers.getMapper(PayDemoOrderConvert.class); - - PayDemoOrderDO convert(PayDemoOrderCreateReqVO bean); - - PayDemoOrderRespVO convert(PayDemoOrderDO bean); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoTransferConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoTransferConvert.java deleted file mode 100644 index 0df9c9d5c2..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoTransferConvert.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.pay.convert.demo; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * @author jason - */ -@Mapper -public interface PayDemoTransferConvert { - - PayDemoTransferConvert INSTANCE = Mappers.getMapper(PayDemoTransferConvert.class); - - PayDemoTransferDO convert(PayDemoTransferCreateReqVO bean); - - PageResult convertPage(PageResult pageResult); -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java deleted file mode 100644 index 7f6b59cc89..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.pay.convert.transfer; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; -import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PayTransferConvert { - - PayTransferConvert INSTANCE = Mappers.getMapper(PayTransferConvert.class); - - PayTransferDO convert(PayTransferCreateReqDTO dto); - - PayTransferUnifiedReqDTO convert2(PayTransferDO dto); - - PayTransferCreateReqDTO convert(PayTransferCreateReqVO vo); - - PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo); - - PayTransferRespVO convert(PayTransferDO bean); - - PageResult convertPage(PageResult pageResult); - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java index f465d0be6d..1c6819a2d1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.demo; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; -import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -10,7 +10,6 @@ import lombok.Data; import java.time.LocalDateTime; -// TODO 芋艿:需要详细 review /** * 示例转账订单 * @@ -22,62 +21,52 @@ import java.time.LocalDateTime; public class PayDemoTransferDO extends BaseDO { /** - * 订单编号 + * 编号,自增 */ @TableId private Long id; /** - * 应用编号 + * 转账渠道 * - * 关联 {@link PayAppDO#getId()} + * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} */ - private Long appId; + private String channelCode; /** - * 转账类型 - *

- * 枚举 {@link PayTransferTypeEnum} + * 转账标题 */ - private Integer type; + private String subject; /** * 转账金额,单位:分 */ private Integer price; + /** + * 收款人账号 + */ + private String userAccount; /** * 收款人姓名 */ private String userName; - /** - * 支付宝登录号 - */ - private String alipayLogonId; - - /** - * 微信 openId - */ - private String openid; - /** * 转账状态 + * + * 枚举 {@link PayTransferStatusEnum} */ private Integer transferStatus; /** * 转账单编号 + * + * 关联 {@link PayTransferDO#getId()} */ private Long payTransferId; - /** - * 转账支付成功渠道 - */ - private String payChannelCode; - - /** - * 转账支付时间 + * 转账成功时间 */ private LocalDateTime transferTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index 8f3563ffbc..fe443e96e3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.transfer; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -16,7 +15,6 @@ import lombok.Data; import java.time.LocalDateTime; import java.util.Map; -// TODO 芋艿:需要详细 review /** * 转账单 DO * @@ -35,7 +33,6 @@ public class PayTransferDO extends BaseDO { /** * 转账单号 - * */ private String no; @@ -70,13 +67,6 @@ public class PayTransferDO extends BaseDO { // ========== 转账相关字段 ========== - /** - * 类型 - * - * 枚举 {@link PayTransferTypeEnum} - */ - private Integer type; - /** * 转账标题 */ @@ -87,6 +77,10 @@ public class PayTransferDO extends BaseDO { */ private Integer price; + /** + * 收款人账号 + */ + private String userAccount; /** * 收款人姓名 */ @@ -104,19 +98,6 @@ public class PayTransferDO extends BaseDO { */ private LocalDateTime successTime; - // ========== 支付宝转账相关字段 ========== - /** - * 支付宝登录号 - */ - private String alipayLogonId; - - - // ========== 微信转账相关字段 ========== - /** - * 微信 openId - */ - private String openid; - // ========== 其它字段 ========== /** @@ -151,7 +132,6 @@ public class PayTransferDO extends BaseDO { /** * 渠道的同步/异步通知的内容 - * */ private String channelNotifyData; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index 57be1a8188..c6d5c9a85c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -8,14 +8,22 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; import java.util.List; @Mapper public interface PayTransferMapper extends BaseMapperX { - default int updateByIdAndStatus(Long id, List status, PayTransferDO updateObj) { + default int updateByIdAndStatus(Long id, List whereStatuses, PayTransferDO updateObj) { return update(updateObj, new LambdaQueryWrapper() - .eq(PayTransferDO::getId, id).in(PayTransferDO::getStatus, status)); + .eq(PayTransferDO::getId, id) + .in(PayTransferDO::getStatus, whereStatuses)); + } + + default int updateByIdAndStatus(Long id, Integer whereStatus, PayTransferDO updateObj) { + return update(updateObj, new LambdaQueryWrapper() + .eq(PayTransferDO::getId, id) + .eq(PayTransferDO::getStatus, whereStatus)); } default PayTransferDO selectByAppIdAndMerchantTransferId(Long appId, String merchantTransferId){ @@ -29,7 +37,6 @@ public interface PayTransferMapper extends BaseMapperX { .eqIfPresent(PayTransferDO::getAppId, reqVO.getAppId()) .eqIfPresent(PayTransferDO::getChannelCode, reqVO.getChannelCode()) .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantTransferId()) - .eqIfPresent(PayTransferDO::getType, reqVO.getType()) .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) @@ -37,8 +44,8 @@ public interface PayTransferMapper extends BaseMapperX { .orderByDesc(PayTransferDO::getId)); } - default List selectListByStatus(Integer status) { - return selectList(PayTransferDO::getStatus, status); + default List selectListByStatus(Collection statuses) { + return selectList(PayTransferDO::getStatus, statuses); } default PayTransferDO selectByAppIdAndNo(Long appId, String no) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java index 27df7ce974..a1b76963f5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java @@ -96,7 +96,6 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { // 2.2 更新支付单到 demo 订单 payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(demoOrder.getId()) .setPayOrderId(payOrderId)); - // 返回 return demoOrder.getId(); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 19c00fd598..85b6b188b1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -3,24 +3,25 @@ package cn.iocoder.yudao.module.pay.service.demo; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.convert.demo.PayDemoTransferConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoTransferMapper; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import jakarta.validation.Validator; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.WAITING; /** * 示例转账业务 Service 实现类 @@ -32,26 +33,38 @@ import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.W public class PayDemoTransferServiceImpl implements PayDemoTransferService { /** - * 接入的实力应用编号 - + * 接入的支付应用标识 + * * 从 [支付管理 -> 应用信息] 里添加 */ - private static final Long TRANSFER_APP_ID = 8L; + private static final String PAY_APP_KEY = "demo"; + @Resource private PayDemoTransferMapper demoTransferMapper; + @Resource private PayTransferService payTransferService; + @Resource - private Validator validator; + private PayTransferApi payTransferApi; @Override - public Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO vo) { - // 1 校验参数 - vo.validate(validator); - // 2 保存示例转账业务表 - PayDemoTransferDO demoTransfer = PayDemoTransferConvert.INSTANCE.convert(vo) - .setAppId(TRANSFER_APP_ID).setTransferStatus(WAITING.getStatus()); + public Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO reqVO) { + // 1. 保存示例转账业务表 + PayDemoTransferDO demoTransfer = BeanUtils.toBean(reqVO, PayDemoTransferDO.class) + .setTransferStatus(PayTransferStatusEnum.WAITING.getStatus()); demoTransferMapper.insert(demoTransfer); + + // 2.1 创建支付单 + Long payTransferId = payTransferApi.createTransfer(new PayTransferCreateReqDTO() + .setChannelCode(reqVO.getChannelCode()) + .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 + .setMerchantTransferId(String.valueOf(demoTransfer.getId())) // 业务的订单编号 + .setSubject(reqVO.getSubject()).setPrice(demoTransfer.getPrice()) // 价格信息 + .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName())); // 收款信息 + // 2.2 更新转账单到 demo 示例转账业务表 + demoTransferMapper.updateById(new PayDemoTransferDO().setId(demoTransfer.getId()) + .setPayTransferId(payTransferId)); return demoTransfer.getId(); } @@ -63,11 +76,11 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { @Override public void updateDemoTransferStatus(Long id, Long payTransferId) { PayTransferDO payTransfer = validateDemoTransferStatusCanUpdate(id, payTransferId); + // TODO @芋艿:这块,需要在优化下; // 更新示例订单状态 if (payTransfer != null) { demoTransferMapper.updateById(new PayDemoTransferDO().setId(id) .setPayTransferId(payTransferId) - .setPayChannelCode(payTransfer.getChannelCode()) .setTransferStatus(payTransfer.getStatus()) .setTransferTime(payTransfer.getSuccessTime())); } @@ -78,9 +91,10 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { if (demoTransfer == null) { throw exception(DEMO_TRANSFER_NOT_FOUND); } + // TODO @芋艿:这里也要更新下; + // 无需更新返回 null if (PayTransferStatusEnum.isSuccess(demoTransfer.getTransferStatus()) || PayTransferStatusEnum.isClosed(demoTransfer.getTransferStatus())) { - // 无需更新返回 null return null; } PayTransferDO transfer = payTransferService.getTransfer(payTransferId); @@ -96,4 +110,5 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { // TODO 校验账号 return transfer; } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index 6bf4757575..fa216f8f90 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java @@ -3,10 +3,8 @@ package cn.iocoder.yudao.module.pay.service.transfer; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; - import jakarta.validation.Valid; /** @@ -16,17 +14,6 @@ import jakarta.validation.Valid; */ public interface PayTransferService { - /** - * 创建转账单,并发起转账 - * - * 此时,会发起转账渠道的调用 - * - * @param reqVO 请求 - * @param userIp 用户 ip - * @return 渠道的返回结果 - */ - PayTransferDO createTransfer(@Valid PayTransferCreateReqVO reqVO, String userIp); - /** * 创建转账单,并发起转账 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index d4a7c9d639..e7ca3a80b0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -5,13 +5,13 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; @@ -25,7 +25,6 @@ import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; import jakarta.annotation.Resource; -import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,9 +32,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.pay.convert.transfer.PayTransferConvert.INSTANCE; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.*; // TODO @jason:等彻底实现完,单测写写; @@ -63,21 +60,6 @@ public class PayTransferServiceImpl implements PayTransferService { private PayNotifyService notifyService; @Resource private PayNoRedisDAO noRedisDAO; - @Resource - private Validator validator; - - @Override - public PayTransferDO createTransfer(PayTransferCreateReqVO reqVO, String userIp) { - // 1. 校验参数 - reqVO.validate(validator); - - // 2. 创建转账单,发起转账 - PayTransferCreateReqDTO req = INSTANCE.convert(reqVO).setUserIp(userIp); - Long transferId = createTransfer(req); - - // 3. 返回转账单 - return getTransfer(transferId); - } @Override public Long createTransfer(PayTransferCreateReqDTO reqDTO) { @@ -90,34 +72,32 @@ public class PayTransferServiceImpl implements PayTransferService { log.error("[createTransfer][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); throw exception(CHANNEL_NOT_FOUND); } - // 1.3 校验转账单已经发起过转账。 + // 1.3 校验转账单已经发起过转账 PayTransferDO transfer = validateTransferCanCreate(reqDTO, payApp.getId()); + // 2. 不存在创建转账单,否则允许使用相同的 no 再次发起转账 if (transfer == null) { - // 2.不存在创建转账单. 否则允许使用相同的 no 再次发起转账 String no = noRedisDAO.generate(TRANSFER_NO_PREFIX); - transfer = INSTANCE.convert(reqDTO) - .setChannelId(channel.getId()) - .setNo(no).setStatus(WAITING.getStatus()) - .setNotifyUrl(payApp.getTransferNotifyUrl()) - .setAppId(channel.getAppId()); + transfer = BeanUtils.toBean(reqDTO, PayTransferDO.class) + .setAppId(channel.getAppId()).setChannelId(channel.getId()) + .setNo(no).setStatus(PayTransferStatusEnum.WAITING.getStatus()) + .setNotifyUrl(payApp.getTransferNotifyUrl()); transferMapper.insert(transfer); } try { // 3. 调用三方渠道发起转账 - PayTransferUnifiedReqDTO transferUnifiedReq = INSTANCE.convert2(transfer) - .setOutTransferNo(transfer.getNo()); - transferUnifiedReq.setNotifyUrl(genChannelTransferNotifyUrl(channel)); + PayTransferUnifiedReqDTO transferUnifiedReq = BeanUtils.toBean(reqDTO, PayTransferUnifiedReqDTO.class) + .setOutTransferNo(transfer.getNo()) + .setNotifyUrl(genChannelTransferNotifyUrl(channel)); PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); // 4. 通知转账结果 getSelf().notifyTransfer(channel, unifiedTransferResp); } catch (Throwable e) { // 注意这里仅打印异常,不进行抛出。 // 原因是:虽然调用支付渠道进行转账发生异常(网络请求超时),实际转账成功。这个结果,后续转账轮询可以拿到。 - // 或者使用相同 no 再次发起转账请求 - log.error("[createTransfer][转账 id({}) requestDTO({}) 发生异常]", transfer.getId(), reqDTO, e); + // 或者,使用相同 no 再次发起转账请求 + log.error("[createTransfer][转账编号({}) requestDTO({}) 发生异常]", transfer.getId(), reqDTO, e); } - return transfer.getId(); } @@ -131,21 +111,23 @@ public class PayTransferServiceImpl implements PayTransferService { return payProperties.getTransferNotifyUrl() + "/" + channel.getId(); } - private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO dto, Long appId) { - PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(appId, dto.getMerchantTransferId()); + private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { + PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(appId, reqDTO.getMerchantTransferId()); if (transfer != null) { - // 已经存在,并且状态不为等待状态。说明已经调用渠道转账并返回结果. + // 已经存在,并且状态不为等待状态:说明已经调用渠道转账并返回结果 if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { - throw exception(PAY_MERCHANT_TRANSFER_EXISTS); + throw exception(PAY_TRANSFER_CREATE_MERCHANT_EXISTS); } - if (ObjectUtil.notEqual(dto.getPrice(), transfer.getPrice())) { - throw exception(PAY_SAME_MERCHANT_TRANSFER_PRICE_NOT_MATCH); + // 校验参数是否一致 + if (ObjectUtil.notEqual(reqDTO.getPrice(), transfer.getPrice())) { + throw exception(PAY_TRANSFER_CREATE_PRICE_NOT_MATCH); } - if (ObjectUtil.notEqual(dto.getType(), transfer.getType())) { - throw exception(PAY_SAME_MERCHANT_TRANSFER_TYPE_NOT_MATCH); + if (ObjectUtil.notEqual(reqDTO.getChannelCode(), transfer.getChannelCode())) { + throw exception(PAY_TRANSFER_CREATE_CHANNEL_NOT_MATCH); } } - // 如果状态为等待状态。不知道渠道转账是否发起成功。 允许使用相同的 no 再次发起转账,渠道会保证幂等 + // 如果状态为等待状态:不知道渠道转账是否发起成功 + // 特殊:允许使用相同的 no 再次发起转账,渠道会保证幂等 return transfer; } @@ -161,94 +143,94 @@ public class PayTransferServiceImpl implements PayTransferService { notifyTransferClosed(channel, notify); } // 转账处理中的回调 - if (PayTransferStatusRespEnum.isInProgress(notify.getStatus())) { - notifyTransferInProgress(channel, notify); + if (PayTransferStatusRespEnum.isProcessing(notify.getStatus())) { + notifyTransferProgressing(channel, notify); } // WAITING 状态无需处理 } - private void notifyTransferInProgress(PayChannelDO channel, PayTransferRespDTO notify) { + private void notifyTransferProgressing(PayChannelDO channel, PayTransferRespDTO notify) { // 1.校验 PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } - if (isInProgress(transfer.getStatus())) { // 如果已经是转账中,直接返回,不用重复更新 + if (PayTransferStatusEnum.isProgressing(transfer.getStatus())) { // 如果已经是转账中,直接返回,不用重复更新 + log.info("[notifyTransferProgressing][transfer({}) 已经是转账中状态,无需更新]", transfer.getId()); return; } - if (!isWaiting(transfer.getStatus())) { + if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING); } - // 2.更新 + + // 2. 更新状态 int updateCounts = transferMapper.updateByIdAndStatus(transfer.getId(), - CollUtil.newArrayList(WAITING.getStatus()), - new PayTransferDO().setStatus(IN_PROGRESS.getStatus())); + PayTransferStatusEnum.WAITING.getStatus(), + new PayTransferDO().setStatus(PayTransferStatusEnum.PROCESSING.getStatus())); if (updateCounts == 0) { throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING); } - log.info("[notifyTransferInProgress][transfer({}) 更新为转账进行中状态]", transfer.getId()); + log.info("[notifyTransferProgressing][transfer({}) 更新为转账进行中状态]", transfer.getId()); } - private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) { - // 1.校验 + // 1. 校验状态 PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } - if (isSuccess(transfer.getStatus())) { // 如果已成功,直接返回,不用重复更新 + if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) { // 如果已成功,直接返回,不用重复更新 + log.info("[notifyTransferSuccess][transfer({}) 已经是成功状态,无需更新]", transfer.getId()); return; } - if (!isPendingStatus(transfer.getStatus())) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_PENDING); + if (!PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { + throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); } - // 2.更新 + + // 2. 更新状态 int updateCounts = transferMapper.updateByIdAndStatus(transfer.getId(), - CollUtil.newArrayList(WAITING.getStatus(), IN_PROGRESS.getStatus()), - new PayTransferDO().setStatus(SUCCESS.getStatus()).setSuccessTime(notify.getSuccessTime()) + CollUtil.newArrayList(PayTransferStatusEnum.WAITING.getStatus(), PayTransferStatusEnum.PROCESSING.getStatus()), + new PayTransferDO().setStatus(PayTransferStatusEnum.SUCCESS.getStatus()) + .setSuccessTime(notify.getSuccessTime()) .setChannelTransferNo(notify.getChannelTransferNo()) - .setChannelId(channel.getId()).setChannelCode(channel.getCode()) .setChannelNotifyData(JsonUtils.toJsonString(notify))); if (updateCounts == 0) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_PENDING); + throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); } - log.info("[updateTransferSuccess][transfer({}) 更新为已转账]", transfer.getId()); + log.info("[notifyTransferSuccess][transfer({}) 更新为已转账]", transfer.getId()); // 3. 插入转账通知记录 - notifyService.createPayNotifyTask(PayNotifyTypeEnum.TRANSFER.getType(), - transfer.getId()); + notifyService.createPayNotifyTask(PayNotifyTypeEnum.TRANSFER.getType(), transfer.getId()); } private void notifyTransferClosed(PayChannelDO channel, PayTransferRespDTO notify) { - // 1.校验 + // 1. 校验状态 PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); } - if (isClosed(transfer.getStatus())) { // 如果已是关闭状态,直接返回,不用重复更新 - log.info("[updateTransferClosed][transfer({}) 已经是关闭状态,无需更新]", transfer.getId()); + if (PayTransferStatusEnum.isClosed(transfer.getStatus())) { // 如果已是关闭状态,直接返回,不用重复更新 + log.info("[notifyTransferClosed][transfer({}) 已经是关闭状态,无需更新]", transfer.getId()); return; } - if (!isPendingStatus(transfer.getStatus())) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_PENDING); + if (!PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { + throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); } - // 2.更新 + // 2. 更新状态 int updateCount = transferMapper.updateByIdAndStatus(transfer.getId(), - CollUtil.newArrayList(WAITING.getStatus(), IN_PROGRESS.getStatus()), - new PayTransferDO().setStatus(CLOSED.getStatus()).setChannelId(channel.getId()) - .setChannelCode(channel.getCode()).setChannelTransferNo(notify.getChannelTransferNo()) - .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg()) - .setChannelNotifyData(JsonUtils.toJsonString(notify))); + CollUtil.newArrayList(PayTransferStatusEnum.WAITING.getStatus(), PayTransferStatusEnum.PROCESSING.getStatus()), + new PayTransferDO().setStatus(PayTransferStatusEnum.CLOSED.getStatus()) + .setChannelTransferNo(notify.getChannelTransferNo()) + .setChannelNotifyData(JsonUtils.toJsonString(notify)) + .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg())); if (updateCount == 0) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_PENDING); + throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); } - log.info("[updateTransferClosed][transfer({}) 更新为关闭状态]", transfer.getId()); + log.info("[notifyTransferClosed][transfer({}) 更新为关闭状态]", transfer.getId()); // 3. 插入转账通知记录 - notifyService.createPayNotifyTask(PayNotifyTypeEnum.TRANSFER.getType(), - transfer.getId()); - + notifyService.createPayNotifyTask(PayNotifyTypeEnum.TRANSFER.getType(), transfer.getId()); } @Override @@ -263,7 +245,8 @@ public class PayTransferServiceImpl implements PayTransferService { @Override public int syncTransfer() { - List list = transferMapper.selectListByStatus(WAITING.getStatus()); + List list = transferMapper.selectListByStatus(CollUtil.newArrayList( + PayTransferStatusEnum.WAITING.getStatus(), PayTransferStatusEnum.PROCESSING.getStatus())); if (CollUtil.isEmpty(list)) { return 0; } @@ -308,4 +291,5 @@ public class PayTransferServiceImpl implements PayTransferService { private PayTransferServiceImpl getSelf() { return SpringUtil.getBean(getClass()); } + } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java index 0f9b48240c..2be8b572bc 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java @@ -66,10 +66,10 @@ public class PayTransferRespDTO { /** * 创建【IN_PROGRESS】状态的转账返回 */ - public static PayTransferRespDTO dealingOf(String channelTransferNo, - String outTransferNo, Object rawData) { + public static PayTransferRespDTO processingOf(String channelTransferNo, + String outTransferNo, Object rawData) { PayTransferRespDTO respDTO = new PayTransferRespDTO(); - respDTO.status = PayTransferStatusRespEnum.IN_PROGRESS.getStatus(); + respDTO.status = PayTransferStatusRespEnum.PROCESSING.getStatus(); respDTO.channelTransferNo = channelTransferNo; respDTO.outTransferNo = outTransferNo; respDTO.rawData = rawData; diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index c1e6077b17..db43821445 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -10,9 +9,6 @@ import org.hibernate.validator.constraints.URL; import java.util.Map; -import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.Alipay; -import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.WxPay; - /** * 统一转账 Request DTO * @@ -27,6 +23,9 @@ public class PayTransferUnifiedReqDTO { @NotEmpty(message = "用户 IP 不能为空") private String userIp; + /** + * 外部转账单编号 + */ @NotEmpty(message = "外部转账单编号不能为空") private String outTransferNo; @@ -44,25 +43,19 @@ public class PayTransferUnifiedReqDTO { @Length(max = 128, message = "转账标题不能超过 128") private String subject; - // TODO @芋艿:userName、alipayLogonId、openid =》channelExtras;另外:validatePayTransferReqDTO 去掉; + /** + * 收款人账号 + * + * 微信场景下:openid + * 支付宝场景下:支付宝账号 + */ + @NotEmpty(message = "收款人账号不能为空") + private String userAccount; /** * 收款人姓名 */ - @NotBlank(message = "收款人姓名不能为空", groups = {Alipay.class}) private String userName; - /** - * 支付宝登录号 - */ - @NotBlank(message = "支付宝登录号不能为空", groups = {Alipay.class}) - private String alipayLogonId; - - /** - * 微信 openId - */ - @NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class}) - private String openid; - /** * 支付渠道的额外参数 */ diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index 52d0a2f4ca..ad4f9ad024 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -11,13 +11,10 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReq import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import lombok.extern.slf4j.Slf4j; import java.util.Map; -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; /** diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index a16516fdb2..8e80512f89 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -40,8 +39,6 @@ import java.util.Objects; import java.util.function.Supplier; import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.ERROR_CONFIGURATION; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE; import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY; @@ -235,10 +232,9 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient { - - ALIPAY_BALANCE(1, "支付宝余额"), - WX_BALANCE(2, "微信余额"), - BANK_CARD(3, "银行卡"), - WALLET_BALANCE(4, "钱包余额"); - - public interface WxPay { - } - - public interface Alipay { - } - - private final Integer type; - private final String name; - - public static final Integer[] ARRAYS = Arrays.stream(values()).map(PayTransferTypeEnum::getType).toArray(Integer[]::new); - - @Override - public Integer[] array() { - return ARRAYS; - } - - public static PayTransferTypeEnum typeOf(Integer type) { - return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); - } - -} From 7653be9d48bcc7dcb3d0804e0dccf40546d57f9f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 8 May 2025 13:09:14 +0800 Subject: [PATCH 05/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E7=A4=BA=E4=BE=8B=E8=BD=AC=E8=B4=A6=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E6=88=90=E7=A4=BA=E4=BE=8B=E6=8F=90=E7=8E=B0?= =?UTF-8?q?=E5=8D=95=EF=BC=8C=E7=90=86=E8=A7=A3=E6=88=90=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E4=BD=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrokerageWithdrawController.java | 2 +- .../BrokerageWithdrawServiceImpl.java | 2 +- .../order/TradeOrderUpdateServiceImpl.java | 2 +- .../api/notify/dto/PayRefundNotifyReqDTO.java | 1 - .../notify/dto/PayTransferNotifyReqDTO.java | 9 +- .../transfer/dto/PayTransferCreateReqDTO.java | 2 +- .../api/transfer/dto/PayTransferRespDTO.java | 25 +++ .../module/pay/enums/ErrorCodeConstants.java | 12 +- .../module/pay/enums/PayChannelEnum.java | 12 +- .../enums/demo/PayDemoWithdrawStatusEnum.java | 42 +++++ .../enums/demo/PayDemoWithdrawTypeEnum.java | 39 +++++ .../enums/transfer/PayTransferStatusEnum.java | 11 ++ .../admin/demo/PayDemoOrderController.java | 2 +- ...er.http => PayDemoWithdrawController.http} | 4 +- ...er.java => PayDemoWithdrawController.java} | 35 +++-- .../transfer/PayDemoTransferCreateReqVO.java | 35 ----- .../vo/transfer/PayDemoTransferRespVO.java | 47 ------ .../withdraw/PayDemoWithdrawCreateReqVO.java | 38 +++++ .../vo/withdraw/PayDemoWithdrawRespVO.java | 44 ++++++ .../vo/PayTransferPageItemRespVO.java | 2 +- .../transfer/vo/PayTransferPageReqVO.java | 2 +- .../admin/transfer/vo/PayTransferRespVO.java | 2 +- ...TransferDO.java => PayDemoWithdrawDO.java} | 45 +++--- .../dataobject/notify/PayNotifyTaskDO.java | 4 - .../dataobject/transfer/PayTransferDO.java | 2 +- .../dal/mysql/demo/PayDemoTransferMapper.java | 17 -- .../dal/mysql/demo/PayDemoWithdrawMapper.java | 24 +++ .../dal/mysql/transfer/PayTransferMapper.java | 6 +- .../service/demo/PayDemoOrderServiceImpl.java | 6 +- .../service/demo/PayDemoTransferService.java | 39 ----- .../demo/PayDemoTransferServiceImpl.java | 147 +++++++++++------- .../service/demo/PayDemoWithdrawService.java | 40 +++++ .../service/notify/PayNotifyServiceImpl.java | 8 +- .../transfer/PayTransferServiceImpl.java | 2 +- .../wallet/PayWalletRechargeServiceImpl.java | 2 +- 35 files changed, 450 insertions(+), 262 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawStatusEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawTypeEnum.java rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/{PayDemoTransferController.http => PayDemoWithdrawController.http} (78%) rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/{PayDemoTransferController.java => PayDemoWithdrawController.java} (52%) delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/{PayDemoTransferDO.java => PayDemoWithdrawDO.java} (62%) delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferService.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index c8d34ecbd0..fd7e475fed 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -89,7 +89,7 @@ public class BrokerageWithdrawController { public CommonResult updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); brokerageWithdrawService.updateBrokerageWithdrawTransferred( - Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); + Long.parseLong(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index b05f558a54..39fe8765eb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -141,7 +141,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()) .setChannelCode("wx_lite") // TODO @芋艿:【转账】这里要处理下; - .setMerchantTransferId(withdraw.getId().toString()) + .setMerchantOrderId(withdraw.getId().toString()) .setPrice(withdraw.getPrice()) .setSubject("佣金提现") .setUserAccount(socialUser.getOpenid()).setUserIp(getClientIP()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 6db33b6302..030cc34317 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -280,7 +280,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { TradeOrderDO order = validateOrderExists(id); // 1.2 校验订单已支付 if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) { - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 + // 特殊:支付单号相同,直接返回,说明重复回调 if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) { log.warn("[updateOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId); return; diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java index 39de1b985b..29e670492c 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.pay.api.notify.dto; -import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java index 995068ba67..982a3be75b 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.pay.api.notify.dto; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.NoArgsConstructor; /** * 转账单的通知 Request DTO @@ -11,14 +14,16 @@ import jakarta.validation.constraints.NotNull; * @author jason */ @Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class PayTransferNotifyReqDTO { - // TODO 芋艿:要不要改成 orderId 待定; /** * 商户转账单号 */ @NotEmpty(message = "商户转账单号不能为空") - private String merchantTransferId; + private String merchantOrderId; /** * 转账订单编号 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index 2d556ceebb..c07e16b425 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -42,7 +42,7 @@ public class PayTransferCreateReqDTO { * 商户转账单编号 */ @NotEmpty(message = "商户转账单编号能为空") - private String merchantTransferId; + private String merchantOrderId; /** * 转账金额,单位:分 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index d287dcc831..b8051be752 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.pay.api.transfer.dto; +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import lombok.Data; +import java.time.LocalDateTime; + @Data public class PayTransferRespDTO { @@ -16,6 +19,22 @@ public class PayTransferRespDTO { */ private String no; + /** + * 转账渠道编码 + * + * 枚举 {@link PayChannelEnum} + */ + private String channelCode; + + // ========== 商户相关字段 ========== + + /** + * 商户转账单编号 + */ + private String merchantOrderId; + + // ========== 转账相关字段 ========== + /** * 转账金额,单位:分 */ @@ -28,4 +47,10 @@ public class PayTransferRespDTO { */ private Integer status; + /** + * 订单转账成功时间 + */ + private LocalDateTime successTime; + + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index ec983d168e..7ee41aa15a 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -85,8 +85,12 @@ public interface ErrorCodeConstants { ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1_007_900_009, "发起退款失败,退款单编号不匹配"); ErrorCode DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1_007_900_010, "发起退款失败,退款单金额不匹配"); - // ========== 示例转账订单 1-007-901-001 ========== - ErrorCode DEMO_TRANSFER_NOT_FOUND = new ErrorCode(1_007_901_001, "示例转账单不存在"); - ErrorCode DEMO_TRANSFER_FAIL_TRANSFER_ID_ERROR = new ErrorCode(1_007_901_002, "转账失败,转账单编号不匹配"); - ErrorCode DEMO_TRANSFER_FAIL_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "转账失败,转账单金额不匹配"); + // ========== 示例提现单 1-007-901-000 ========== + ErrorCode DEMO_WITHDRAW_NOT_FOUND = new ErrorCode(1_007_901_000, "示例提现单不存在"); + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_007_901_001, "更新示例提现单状态失败,支付转账单编号不匹配"); + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_007_901_002, "更新示例提现单状态失败,支付转账单状态不是【转账成功】或【转账失败】状态"); + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "更新示例提现单状态失败,支付转账单金额不匹配"); + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS = new ErrorCode(1_007_901_004, "更新示例提现单状态失败,支付转账单商户订单号不匹配"); + ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH = new ErrorCode(1_007_901_005, "更新示例提现单状态失败,支付转账单渠道不匹配"); + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/PayChannelEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/PayChannelEnum.java index 52d35d2aa9..1c577e2f54 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/PayChannelEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/PayChannelEnum.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.pay.enums; +import cn.iocoder.yudao.framework.common.core.ArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; + /** * 支付渠道的编码的枚举 * @@ -10,7 +13,7 @@ import lombok.Getter; */ @Getter @AllArgsConstructor -public enum PayChannelEnum { +public enum PayChannelEnum implements ArrayValuable { WX_PUB("wx_pub", "微信 JSAPI 支付"), // 公众号网页 WX_LITE("wx_lite", "微信小程序支付"), @@ -28,6 +31,8 @@ public enum PayChannelEnum { WALLET("wallet", "钱包支付"); + public static final String[] ARRAYS = Arrays.stream(values()).map(PayChannelEnum::getCode).toArray(String[]::new); + /** * 编码 * @@ -39,4 +44,9 @@ public enum PayChannelEnum { */ private final String name; + @Override + public String[] array() { + return ARRAYS; + } + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawStatusEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawStatusEnum.java new file mode 100644 index 0000000000..d65bd3b7f5 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawStatusEnum.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.pay.enums.demo; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Objects; + +/** + * 示例提现单的状态枚举 + * + * @author jason + */ +@Getter +@AllArgsConstructor +public enum PayDemoWithdrawStatusEnum { + + WAITING(0, "等待提现"), + SUCCESS(10, "提现成功"), + CLOSED(20, "提现关闭"); + + /** + * 状态 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + public static boolean isSuccess(Integer status) { + return Objects.equals(status, SUCCESS.getStatus()); + } + + public static boolean isClosed(Integer status) { + return Objects.equals(status, CLOSED.getStatus()); + } + + public static boolean isWaiting(Integer status) { + return Objects.equals(status, WAITING.getStatus()); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawTypeEnum.java new file mode 100644 index 0000000000..c2d94698e9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/demo/PayDemoWithdrawTypeEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.enums.demo; + +import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 示例提现单的类型枚举 + * + * @author owen + */ +@AllArgsConstructor +@Getter +public enum PayDemoWithdrawTypeEnum implements ArrayValuable { + + WECHAT(2, "微信"), + ALIPAY(1, "支付宝"), + WALLET(3, "钱包"), + ; + + public static final Integer[] ARRAYS = Arrays.stream(values()).map(PayDemoWithdrawTypeEnum::getType).toArray(Integer[]::new); + + /** + * 类型 + */ + private final Integer type; + /** + * 名字 + */ + private final String name; + + @Override + public Integer[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java index 27d37c7bd3..cfb68987ee 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java @@ -48,9 +48,20 @@ public enum PayTransferStatusEnum { * 是否处于待转账或者转账中的状态 * * @param status 状态 + * @return 是否 */ public static boolean isWaitingOrProcessing(Integer status) { return isWaiting(status) || isProgressing(status); } + /** + * 是否处于成功或者关闭中的状态 + * + * @param status 状态 + * @return 是否 + */ + public static boolean isSuccessOrClosed(Integer status) { + return isSuccess(status) || isClosed(status); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 8eebc223b6..25f0bf0f7b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Tag(name = "管理后台 - 示例订单") +@Tag(name = "管理后台 - 示例订单") // 目的:演示支付、退款功能 @RestController @RequestMapping("/pay/demo-order") @Validated diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http similarity index 78% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http index 08f7c24a60..2426c26243 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.http +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http @@ -1,11 +1,11 @@ ### 请求 /pay/pay/demo-order 接口 => 成功 -POST {{baseUrl}}/pay/demo-transfer/create +POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json tenant-id: {{adminTenantId}} { - "channelCode": "alipay_pc", + "type": 1, "subject": "测试转账", "price": 10, "userAccount": "oespxk7368@sandbox.com", diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java similarity index 52% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index be31ae51a5..02847a3363 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoTransferController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -5,10 +5,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; -import cn.iocoder.yudao.module.pay.service.demo.PayDemoTransferService; +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawRespVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; +import cn.iocoder.yudao.module.pay.service.demo.PayDemoWithdrawService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -19,33 +19,34 @@ import org.springframework.web.bind.annotation.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Tag(name = "管理后台 - 示例转账单") +@Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能 @RestController -@RequestMapping("/pay/demo-transfer") +@RequestMapping("/pay/demo-withdraw") @Validated -public class PayDemoTransferController { +public class PayDemoWithdrawController { + @Resource - private PayDemoTransferService demoTransferService; + private PayDemoWithdrawService demoWithdrawService; @PostMapping("/create") - @Operation(summary = "创建示例转账订单") - public CommonResult createDemoTransfer(@Valid @RequestBody PayDemoTransferCreateReqVO createReqVO) { - Long id = demoTransferService.createDemoTransfer(createReqVO); + @Operation(summary = "创建示例提现单") + public CommonResult createDemoTransfer(@Valid @RequestBody PayDemoWithdrawCreateReqVO createReqVO) { + Long id = demoWithdrawService.createDemoWithdraw(createReqVO); return success(id); } @GetMapping("/page") - @Operation(summary = "获得示例转账订单分页") - public CommonResult> getDemoTransferPage(@Valid PageParam pageVO) { - PageResult pageResult = demoTransferService.getDemoTransferPage(pageVO); - return success(BeanUtils.toBean(pageResult, PayDemoTransferRespVO.class)); + @Operation(summary = "获得示例提现单分页") + public CommonResult> getDemoTransferPage(@Valid PageParam pageVO) { + PageResult pageResult = demoWithdrawService.getDemoWithdrawPage(pageVO); + return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class)); } @PostMapping("/update-status") - @Operation(summary = "更新示例转账订单的转账状态") // 由 pay-module 转账服务,进行回调 + @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 public CommonResult updateDemoTransferStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { - demoTransferService.updateDemoTransferStatus(Long.valueOf(notifyReqDTO.getMerchantTransferId()), + demoWithdrawService.updateDemoWithdrawStatus(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java deleted file mode 100644 index f749dff507..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -@Schema(description = "管理后台 - 示例转账单创建 Request VO") -@Data -public class PayDemoTransferCreateReqVO { - - @Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_lite") - @NotEmpty(message = "转账渠道不能为空") - private String channelCode; - - @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿是一种菜") - @NotEmpty(message = "转账标题不能为空") - private String subject; - - @Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - @NotNull(message = "转账金额不能为空") - @Min(value = 1, message = "转账金额必须大于零") - private Integer price; - - @Schema(description = "收款人账号", requiredMode= Schema.RequiredMode.REQUIRED, example = "test1") - @NotBlank(message = "收款人账号不能为空") - private String userAccount; - - @Schema(description = "收款人姓名", example = "test1") - @NotBlank(message = "收款人姓名不能为空") - private String userName; - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferRespVO.java deleted file mode 100644 index 3fdab57c3e..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferRespVO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 示例业务转账订单 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class PayDemoTransferRespVO { - - @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long appId; - - @Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22338") - private Integer price; - - @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer type; - - @Schema(description = "收款人姓名", example = "test") - private String userName; - - @Schema(description = "支付宝登录号", example = "32167") - private String alipayLogonId; - - @Schema(description = "微信 openId", example = "31139") - private String openid; - - @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer transferStatus; - - @Schema(description = "转账订单编号", example = "23695") - private Long payTransferId; - - @Schema(description = "转账支付成功渠道") - private String payChannelCode; - - @Schema(description = "转账支付时间") - private LocalDateTime transferTime; -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java new file mode 100644 index 0000000000..56837a3725 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 示例提现单创建 Request VO") +@Data +public class PayDemoWithdrawCreateReqVO { + + @Schema(description = "提现标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿是一种菜") + @NotEmpty(message = "提现标题不能为空") + private String subject; + + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "提现金额不能为空") + @Min(value = 1, message = "提现金额必须大于零") + private Integer price; + + @Schema(description = "收款人账号", requiredMode= Schema.RequiredMode.REQUIRED, example = "test1") + @NotBlank(message = "收款人账号不能为空") + private String userAccount; + + @Schema(description = "收款人姓名", example = "test1") + @NotBlank(message = "收款人姓名不能为空") + private String userName; + + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "提现方式不能为空") + @InEnum(PayDemoWithdrawTypeEnum.class) + private Integer type; + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java new file mode 100644 index 0000000000..c99467b6a1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 示例转账单创建 Request VO") +@Data +public class PayDemoWithdrawRespVO { + + @Schema(description = "转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "提现标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "吃饭报销") + private String subject; + + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22338") + private Integer price; + + @Schema(description = "收款人姓名", example = "test") + private String userName; + + @Schema(description = "收款人账号", example = "32167") + private String userAccount; + + @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer type; + + @Schema(description = "提现状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Integer status; + + // ========== 转账相关字段 ========== + + @Schema(description = "转账单编号", example = "23695") + private Long payTransferId; + + @Schema(description = "转账渠道") + private String transferChannelCode; + + @Schema(description = "转账成功时间") + private LocalDateTime transferTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java index 9440142097..9a7e46f0c7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java @@ -28,7 +28,7 @@ public class PayTransferPageItemRespVO { private String channelCode; @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") - private String merchantTransferId; + private String merchantOrderId; @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Integer type; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java index eeb9a0285b..e00b48f807 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java @@ -24,7 +24,7 @@ public class PayTransferPageReqVO extends PageParam { private String channelCode; @Schema(description = "商户转账单编号", example = "17481") - private String merchantTransferId; + private String merchantOrderId; @Schema(description = "转账状态", example = "2") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java index 6b65dfd6bd..aec3a274bd 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java @@ -25,7 +25,7 @@ public class PayTransferRespVO { private String channelCode; @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") - private String merchantTransferId; + private String merchantOrderId; @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Integer type; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java similarity index 62% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java index 1c6819a2d1..af38cadaa9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.demo; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; -import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawStatusEnum; +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -11,35 +12,27 @@ import lombok.Data; import java.time.LocalDateTime; /** - * 示例转账订单 + * 示例提现订单 * * 演示业务系统的转账业务 */ -@TableName(value ="pay_demo_transfer", autoResultMap = true) -@KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName(value ="pay_demo_withdraw", autoResultMap = true) +@KeySequence("pay_demo_withdraw_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -public class PayDemoTransferDO extends BaseDO { +public class PayDemoWithdrawDO extends BaseDO { /** - * 编号,自增 + * 提现单编号,自增 */ @TableId private Long id; /** - * 转账渠道 - * - * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} - */ - private String channelCode; - - /** - * 转账标题 + * 提现标题 */ private String subject; - /** - * 转账金额,单位:分 + * 提现金额,单位:分 */ private Integer price; @@ -53,11 +46,19 @@ public class PayDemoTransferDO extends BaseDO { private String userName; /** - * 转账状态 + * 提现方式 * - * 枚举 {@link PayTransferStatusEnum} + * 枚举 {@link PayDemoWithdrawTypeEnum} */ - private Integer transferStatus; + private Integer type; + /** + * 提现状态 + * + * 枚举 {@link PayDemoWithdrawStatusEnum} + */ + private Integer status; + + // ========== 转账相关字段 ========== /** * 转账单编号 @@ -65,6 +66,12 @@ public class PayDemoTransferDO extends BaseDO { * 关联 {@link PayTransferDO#getId()} */ private Long payTransferId; + /** + * 转账渠道 + * + * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} + */ + private String transferChannelCode; /** * 转账成功时间 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java index 9f9ee7fefb..ec2c4a7046 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java @@ -66,10 +66,6 @@ public class PayNotifyTaskDO extends TenantBaseDO { * 商户订单编号 */ private String merchantOrderId; - /** - * 商户转账单编号 - */ - private String merchantTransferId; /** * 通知状态 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index fe443e96e3..cadf815609 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -63,7 +63,7 @@ public class PayTransferDO extends BaseDO { * * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 */ - private String merchantTransferId; + private String merchantOrderId; // ========== 转账相关字段 ========== diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java deleted file mode 100644 index 77c7ba0478..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.pay.dal.mysql.demo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayDemoTransferMapper extends BaseMapperX { - - default PageResult selectPage(PageParam pageParam){ - return selectPage(pageParam, new LambdaQueryWrapperX() - .orderByDesc(PayDemoTransferDO::getId)); - } -} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java new file mode 100644 index 0000000000..a1078d7805 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.demo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PayDemoWithdrawMapper extends BaseMapperX { + + default PageResult selectPage(PageParam pageParam){ + return selectPage(pageParam, new LambdaQueryWrapperX() + .orderByDesc(PayDemoWithdrawDO::getId)); + } + + default int updateByIdAndStatus(Long id, Integer status, PayDemoWithdrawDO updateObj) { + return update(updateObj, new LambdaQueryWrapperX() + .eq(PayDemoWithdrawDO::getId, id) + .eq(PayDemoWithdrawDO::getStatus, status)); + } + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index c6d5c9a85c..4e7c90e937 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -26,9 +26,9 @@ public interface PayTransferMapper extends BaseMapperX { .eq(PayTransferDO::getStatus, whereStatus)); } - default PayTransferDO selectByAppIdAndMerchantTransferId(Long appId, String merchantTransferId){ + default PayTransferDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { return selectOne(PayTransferDO::getAppId, appId, - PayTransferDO::getMerchantTransferId, merchantTransferId); + PayTransferDO::getMerchantOrderId, merchantOrderId); } default PageResult selectPage(PayTransferPageReqVO reqVO) { @@ -36,7 +36,7 @@ public interface PayTransferMapper extends BaseMapperX { .eqIfPresent(PayTransferDO::getNo, reqVO.getNo()) .eqIfPresent(PayTransferDO::getAppId, reqVO.getAppId()) .eqIfPresent(PayTransferDO::getChannelCode, reqVO.getChannelCode()) - .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantTransferId()) + .eqIfPresent(PayTransferDO::getMerchantOrderId, reqVO.getMerchantOrderId()) .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java index a1b76963f5..bf34278e3c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java @@ -119,14 +119,14 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { } // 1.2 校验订单已支付 if (order.getPayStatus()) { - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 + // 特殊:支付单号相同,直接返回,说明重复回调 if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) { log.warn("[updateDemoOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId); return; } // 异常:支付单号不同,说明支付单号错误 - log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", - order, payOrderId, toJsonString(order)); + log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!]", + order, payOrderId); throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferService.java deleted file mode 100644 index 9563c2a691..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferService.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.pay.service.demo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; - -import jakarta.validation.Valid; - -/** - * 示例转账业务 Service 接口 - * - * @author jason - */ -public interface PayDemoTransferService { - - /** - * 创建转账业务示例订单 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO createReqVO); - - /** - * 获得转账业务示例订单分页 - * - * @param pageVO 分页查询参数 - */ - PageResult getDemoTransferPage(PageParam pageVO); - - /** - * 更新转账业务示例订单的转账状态 - * - * @param id 编号 - * @param payTransferId 转账单编号 - */ - void updateDemoTransferStatus(Long id, Long payTransferId); -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 85b6b188b1..083e49a032 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -3,22 +3,24 @@ package cn.iocoder.yudao.module.pay.service.demo; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; -import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; -import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoTransferMapper; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; +import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoWithdrawMapper; +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawStatusEnum; +import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; -import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.util.Objects; - import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; @@ -30,7 +32,8 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; */ @Service @Validated -public class PayDemoTransferServiceImpl implements PayDemoTransferService { +@Slf4j +public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { /** * 接入的支付应用标识 @@ -40,75 +43,113 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { private static final String PAY_APP_KEY = "demo"; @Resource - private PayDemoTransferMapper demoTransferMapper; - - @Resource - private PayTransferService payTransferService; + private PayDemoWithdrawMapper demoTransferMapper; @Resource private PayTransferApi payTransferApi; @Override - public Long createDemoTransfer(@Valid PayDemoTransferCreateReqVO reqVO) { - // 1. 保存示例转账业务表 - PayDemoTransferDO demoTransfer = BeanUtils.toBean(reqVO, PayDemoTransferDO.class) - .setTransferStatus(PayTransferStatusEnum.WAITING.getStatus()); - demoTransferMapper.insert(demoTransfer); + public Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO reqVO) { + // 1. 保存示例提现单 + PayDemoWithdrawDO withdraw = BeanUtils.toBean(reqVO, PayDemoWithdrawDO.class) + .setTransferChannelCode(getTransferChannelCode(reqVO.getType())) + .setStatus(PayTransferStatusEnum.WAITING.getStatus()); + demoTransferMapper.insert(withdraw); // 2.1 创建支付单 Long payTransferId = payTransferApi.createTransfer(new PayTransferCreateReqDTO() - .setChannelCode(reqVO.getChannelCode()) - .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 - .setMerchantTransferId(String.valueOf(demoTransfer.getId())) // 业务的订单编号 - .setSubject(reqVO.getSubject()).setPrice(demoTransfer.getPrice()) // 价格信息 + .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 + .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 + .setSubject(reqVO.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName())); // 收款信息 - // 2.2 更新转账单到 demo 示例转账业务表 - demoTransferMapper.updateById(new PayDemoTransferDO().setId(demoTransfer.getId()) + // 2.2 更新转账单到 demo 示例提现单 + demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(withdraw.getId()) .setPayTransferId(payTransferId)); - return demoTransfer.getId(); + return withdraw.getId(); + } + + private String getTransferChannelCode(Integer type) { + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.ALIPAY.getType())) { + return PayChannelEnum.ALIPAY_PC.getCode(); + } + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.WECHAT.getType())) { + return PayChannelEnum.WX_LITE.getCode(); + } + if (ObjectUtil.equal(type, PayDemoWithdrawTypeEnum.WALLET.getType())) { + return PayChannelEnum.WALLET.getCode(); + } + throw new IllegalArgumentException("未知提现方式:" + type); } @Override - public PageResult getDemoTransferPage(PageParam pageVO) { + public PageResult getDemoWithdrawPage(PageParam pageVO) { return demoTransferMapper.selectPage(pageVO); } @Override - public void updateDemoTransferStatus(Long id, Long payTransferId) { - PayTransferDO payTransfer = validateDemoTransferStatusCanUpdate(id, payTransferId); - // TODO @芋艿:这块,需要在优化下; - // 更新示例订单状态 - if (payTransfer != null) { - demoTransferMapper.updateById(new PayDemoTransferDO().setId(id) - .setPayTransferId(payTransferId) - .setTransferStatus(payTransfer.getStatus()) - .setTransferTime(payTransfer.getSuccessTime())); + public void updateDemoWithdrawStatus(Long id, Long payTransferId) { + // 1.1 校验转账单是否存在 + PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id); + if (withdraw == null) { + log.error("[updateDemoWithdrawStatus][withdraw({}) payOrder({}) 不存在提现单,请进行处理!]", id, payTransferId); + throw exception(DEMO_WITHDRAW_NOT_FOUND); } + // 1.2 校验转账单已成结束(成功或失败) + if (PayDemoWithdrawStatusEnum.isSuccess(withdraw.getStatus()) + || PayDemoWithdrawStatusEnum.isClosed(withdraw.getStatus())) { + // 特殊:转账单编号相同,直接返回,说明重复回调 + if (ObjectUtil.equal(withdraw.getPayTransferId(), payTransferId)) { + log.warn("[updateDemoWithdrawStatus][withdraw({}) 已结束,且转账单编号相同({}),直接返回]", withdraw, payTransferId); + return; + } + // 异常:转账单编号不同,说明转账单编号错误 + log.error("[updateDemoWithdrawStatus][withdraw({}) 转账单不匹配({}),请进行处理!]", withdraw, payTransferId); + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR); + } + + // 2. 校验提现单的合法性 + PayTransferRespDTO payTransfer = validateDemoTransferStatusCanUpdate(withdraw, payTransferId); + + // 3. 更新示例订单状态 + demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(id) + .setPayTransferId(payTransferId) + .setStatus(payTransfer.getStatus()) + .setTransferTime(payTransfer.getSuccessTime())); } - private PayTransferDO validateDemoTransferStatusCanUpdate(Long id, Long payTransferId) { - PayDemoTransferDO demoTransfer = demoTransferMapper.selectById(id); - if (demoTransfer == null) { - throw exception(DEMO_TRANSFER_NOT_FOUND); - } - // TODO @芋艿:这里也要更新下; - // 无需更新返回 null - if (PayTransferStatusEnum.isSuccess(demoTransfer.getTransferStatus()) - || PayTransferStatusEnum.isClosed(demoTransfer.getTransferStatus())) { - return null; - } - PayTransferDO transfer = payTransferService.getTransfer(payTransferId); - if (transfer == null) { + private PayTransferRespDTO validateDemoTransferStatusCanUpdate(PayDemoWithdrawDO withdraw, Long payTransferId) { + // 1. 校验转账单是否存在 + PayTransferRespDTO payTransfer = payTransferApi.getTransfer(payTransferId); + if (payTransfer == null) { + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 不存在,请进行处理!]", withdraw.getId(), payTransferId); throw exception(PAY_TRANSFER_NOT_FOUND); } - if (!Objects.equals(demoTransfer.getPrice(), transfer.getPrice())) { - throw exception(DEMO_TRANSFER_FAIL_PRICE_NOT_MATCH); + + // 2.1 校验转账单已成功 + if (!PayTransferStatusEnum.isSuccessOrClosed(payTransfer.getStatus())) { + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 未结束,请进行处理!payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED); } - if (ObjectUtil.notEqual(transfer.getMerchantTransferId(), id.toString())) { - throw exception(DEMO_TRANSFER_FAIL_TRANSFER_ID_ERROR); + // 2.2 校验转账金额一致 + if (ObjectUtil.notEqual(payTransfer.getPrice(), withdraw.getPrice())) { + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } - // TODO 校验账号 - return transfer; + // 2.3 校验转账订单匹配(二次) + if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); + } + // 2.4 校验转账渠道一致 + if (ObjectUtil.notEqual(payTransfer.getChannelCode(), withdraw.getTransferChannelCode())) { + log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账渠道不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); + throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH); + } + return payTransfer; } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java new file mode 100644 index 0000000000..48af5d038b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.pay.service.demo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; + +import jakarta.validation.Valid; + +/** + * 示例提现单 Service 接口 + * + * @author jason + */ +public interface PayDemoWithdrawService { + + /** + * 创建示例提现单 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO createReqVO); + + /** + * 获得示例提现单分页 + * + * @param pageVO 分页查询参数 + */ + PageResult getDemoWithdrawPage(PageParam pageVO); + + /** + * 更新示例提现单的状态 + * + * @param id 编号 + * @param payTransferId 转账单编号 + */ + void updateDemoWithdrawStatus(Long id, Long payTransferId); + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java index ba4c7ee9b4..bf56680544 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java @@ -108,8 +108,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { PayTransferDO transfer = transferService.getTransfer(task.getDataId()); - task.setAppId(transfer.getAppId()).setMerchantTransferId(transfer.getMerchantTransferId()) - .setNotifyUrl(transfer.getNotifyUrl()); + task.setAppId(transfer.getAppId()) + .setMerchantOrderId(transfer.getMerchantOrderId()).setNotifyUrl(transfer.getNotifyUrl()); } // 执行插入 @@ -225,8 +225,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { request = PayRefundNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) .payRefundId(task.getDataId()).build(); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { - request = new PayTransferNotifyReqDTO().setMerchantTransferId(task.getMerchantTransferId()) - .setPayTransferId(task.getDataId()); + request = PayTransferNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) + .payTransferId(task.getDataId()).build(); } else { throw new RuntimeException("未知的通知任务类型:" + JsonUtils.toJsonString(task)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index e7ca3a80b0..a3c5f2de9e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -112,7 +112,7 @@ public class PayTransferServiceImpl implements PayTransferService { } private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { - PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(appId, reqDTO.getMerchantTransferId()); + PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantOrderId()); if (transfer != null) { // 已经存在,并且状态不为等待状态:说明已经调用渠道转账并返回结果 if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java index b332731faf..d7144f60e3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java @@ -122,7 +122,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { } // 1.2 校验钱包充值是否可以支付 if (recharge.getPayStatus()) { - // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调 + // 特殊:支付单号相同,直接返回,说明重复回调 if (ObjectUtil.equals(recharge.getPayOrderId(), payOrderId)) { log.warn("[updateWalletRechargerPaid][recharge({}) 已支付,且支付单号相同({}),直接返回]", recharge, payOrderId); return; From f81dc105a2a4a438d43f5a6487b8cf25f68ddd93 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 8 May 2025 13:57:49 +0800 Subject: [PATCH 06/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91AbstractAlipayPayClient=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=AE=9D=E5=A2=9E=E5=8A=A0=E5=9B=9E=E8=B0=83=E8=A7=A3?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/alipay/AbstractAlipayPayClient.java | 68 ++++++++++++++----- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index 8e80512f89..7439b33aca 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -81,24 +81,11 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body, Map headers) throws Throwable { // 1. 校验回调数据 - Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8); - boolean verify; - if (Objects.equals(config.getMode(), MODE_PUBLIC_KEY)) { - verify = AlipaySignature.rsaCheckV1(params, config.getAlipayPublicKey(), - StandardCharsets.UTF_8.name(), config.getSignType()); - } else if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { - // 由于 rsaCertCheckV1 的第二个参数是 path,所以不能这么调用!!!通过阅读源码,发现可以采用如下方式! - X509Certificate cert = AntCertificationUtil.getCertFromContent(config.getAlipayPublicCertContent()); - String publicKey = Base64.encodeBase64String(cert.getEncoded()); - verify = AlipaySignature.rsaCheckV1(bodyObj, publicKey, - StandardCharsets.UTF_8.name(), config.getSignType()); - } else { - throw new IllegalArgumentException("未知的公钥类型:" + config.getMode()); - } - Assert.isTrue(verify, "验签结果不通过"); + verifyNotifyData(params); // 2. 解析订单的状态 // 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂 + Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8); Integer status = parseStatus(bodyObj.get("trade_status")); // 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功 if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) { @@ -324,10 +311,55 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient params, String body, Map headers) { - throw new UnsupportedOperationException("未实现"); + protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) + throws Throwable { + // 1. 校验回调数据 + verifyNotifyData(params); + + // 2. 解析转账状态 + Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8); + String status = bodyObj.get("status"); + String outBizNo = bodyObj.get("out_biz_no"); + String orderId = bodyObj.get("order_id"); + String payDate = bodyObj.get("pay_date"); + + // 3. 根据状态返回对应的结果 + if (Objects.equals(status, "SUCCESS")) { + return PayTransferRespDTO.successOf(orderId, parseTime(payDate), outBizNo, bodyObj); + } + if (Objects.equals(status, "DEALING")) { + return PayTransferRespDTO.processingOf(orderId, outBizNo, bodyObj); + } + if (ObjectUtils.equalsAny(status, "REFUND", "FAIL")) { + return PayTransferRespDTO.closedOf(bodyObj.get("sub_code"), bodyObj.get("sub_msg"), + outBizNo, bodyObj); + } + return PayTransferRespDTO.waitingOf(orderId, outBizNo, bodyObj); + } + + /** + * 校验回调数据 + * + * @param params 回调参数 + * @throws Throwable 验签失败时抛出异常 + */ + protected void verifyNotifyData(Map params) throws Throwable { + boolean verify; + if (Objects.equals(config.getMode(), MODE_PUBLIC_KEY)) { + verify = AlipaySignature.rsaCheckV1(params, config.getAlipayPublicKey(), + StandardCharsets.UTF_8.name(), config.getSignType()); + } else if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { + // 由于 rsaCertCheckV1 的第二个参数是 path,所以不能这么调用!!!通过阅读源码,发现可以采用如下方式! + X509Certificate cert = AntCertificationUtil.getCertFromContent(config.getAlipayPublicCertContent()); + String publicKey = Base64.encodeBase64String(cert.getEncoded()); + verify = AlipaySignature.rsaCheckV1(params, publicKey, + StandardCharsets.UTF_8.name(), config.getSignType()); + } else { + throw new IllegalArgumentException("未知的公钥类型:" + config.getMode()); + } + Assert.isTrue(verify, "验签结果不通过"); } // ========== 各种工具方法 ========== From 38c76806a3da36f8b97a5943c1410c94011623b0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 8 May 2025 23:31:23 +0800 Subject: [PATCH 07/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E7=9A=84?= =?UTF-8?q?=E8=BD=AC=E8=B4=A6=EF=BC=8C=E6=8E=A5=E5=85=A5=E6=96=B0=E7=9A=84?= =?UTF-8?q?=20API=EF=BC=88=E9=9C=80=E8=A6=81=E7=BB=A7=E7=BB=AD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=8C=3D=20=3D=20=E7=9C=9F=E9=BA=BB=E7=83=A6?= =?UTF-8?q?=EF=BC=89=20feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E3=80=91=E9=92=B1=E5=8C=85=E6=94=AF=E6=8C=81=E8=BD=AC=E8=B4=A6?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrokerageWithdrawServiceImpl.java | 2 +- .../transfer/dto/PayTransferCreateReqDTO.java | 47 +++++++ .../enums/wallet/PayWalletBizTypeEnum.java | 2 +- .../admin/demo/PayDemoWithdrawController.http | 29 ++++- .../withdraw/PayDemoWithdrawCreateReqVO.java | 1 - .../admin/order/PayOrderController.java | 14 ++- .../app/order/AppPayOrderController.java | 15 ++- .../dal/mysql/transfer/PayTransferMapper.java | 4 + .../framework/pay/core/WalletPayClient.java | 87 ++++++++++--- .../demo/PayDemoTransferServiceImpl.java | 9 +- .../service/transfer/PayTransferService.java | 8 ++ .../transfer/PayTransferServiceImpl.java | 5 + .../pay/service/wallet/PayWalletService.java | 13 +- .../service/wallet/PayWalletServiceImpl.java | 6 +- .../transfer/PayTransferUnifiedReqDTO.java | 2 + .../impl/weixin/AbstractWxPayClient.java | 92 +++++++------- .../bean/transfer/TransferBatchesRequest.java | 118 ------------------ 17 files changed, 249 insertions(+), 205 deletions(-) delete mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 39fe8765eb..240e771cf8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -113,7 +113,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { payWalletApi.addWalletBalance(new PayWalletAddBalanceReqDTO() .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) - .setBizType(PayWalletBizTypeEnum.BROKERAGE_WITHDRAW.getType()).setBizId(withdraw.getId().toString()) + .setBizType(PayWalletBizTypeEnum.TRANSFER.getType()).setBizId(withdraw.getId().toString()) .setPrice(withdraw.getPrice())); // 1.2 微信 API } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) { diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index c07e16b425..ce92080191 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -1,10 +1,15 @@ package cn.iocoder.yudao.module.pay.api.transfer.dto; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -70,4 +75,46 @@ public class PayTransferCreateReqDTO { */ private String userName; + /** + * 【微信】现金营销场景 + * + * @param activityName 活动名称 + * @param rewardDescription 奖励说明 + * @return channelExtras + */ + public static Map buildWeiXinChannelExtra1000(String activityName, String rewardDescription) { + return buildWeiXinChannelExtra(1000, + "活动名称", activityName, + "奖励说明", rewardDescription); + } + + /** + * 【微信】企业报销场景 + * + * @param expenseType 报销类型 + * @param expenseDescription 报销说明 + * @return channelExtras + */ + public static Map buildWeiXinChannelExtra1006(String expenseType, String expenseDescription) { + return buildWeiXinChannelExtra(1006, + "报销类型", expenseType, + "报销说明", expenseDescription); + } + + private static Map buildWeiXinChannelExtra(Integer sceneId, String... values) { + Map channelExtras = new HashMap<>(); + // 构建场景报备信息列表 + List> sceneReportInfos = new ArrayList<>(); + for (int i = 0; i < values.length; i += 2) { + Map info = new HashMap<>(); + info.put("infoType", values[i]); + info.put("infoContent", values[i + 1]); + sceneReportInfos.add(info); + } + // 设置场景ID和场景报备信息 + channelExtras.put("sceneId", StrUtil.toString(sceneId)); + channelExtras.put("sceneReportInfos", JsonUtils.toJsonString(sceneReportInfos)); + return channelExtras; + } + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java index 30336da76e..f2987cfe21 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java @@ -20,7 +20,7 @@ public enum PayWalletBizTypeEnum implements ArrayValuable { PAYMENT(3, "支付"), PAYMENT_REFUND(4, "支付退款"), UPDATE_BALANCE(5, "更新余额"), - BROKERAGE_WITHDRAW(6, "分佣提现"); + TRANSFER(6, "转账"); /** * 业务分类 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http index 2426c26243..fa18693cf2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http @@ -1,4 +1,4 @@ -### 请求 /pay/pay/demo-order 接口 => 成功 +### 请求 /pay/pay/demo-order 接口(支付宝) => 成功 POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -10,4 +10,31 @@ tenant-id: {{adminTenantId}} "price": 10, "userAccount": "oespxk7368@sandbox.com", "userName": "oespxk7368" +} + +### 请求 /pay/pay/demo-order 接口(微信余额) => 成功 +POST {{baseUrl}}/pay/demo-withdraw/create +Authorization: Bearer {{token}} +Content-Type: application/json +tenant-id: {{adminTenantId}} + +{ + "type": 2, + "subject": "测试转账", + "price": 1, + "userAccount": "oiSC85elO_OZogXODC5RoGyXamK4", + "userName": "芋艿" +} + +### 请求 /pay/pay/demo-order 接口(钱包余额) => 成功 +POST {{baseUrl}}/pay/demo-withdraw/create +Authorization: Bearer {{token}} +Content-Type: application/json +tenant-id: {{adminTenantId}} + +{ + "type": 3, + "subject": "测试转账", + "price": 1, + "userAccount": "1" } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java index 56837a3725..de03533648 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java @@ -27,7 +27,6 @@ public class PayDemoWithdrawCreateReqVO { private String userAccount; @Schema(description = "收款人姓名", example = "test1") - @NotBlank(message = "收款人姓名不能为空") private String userName; @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java index 1716d8ae9a..7a6f893bb8 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java @@ -12,10 +12,12 @@ import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; import com.google.common.collect.Maps; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -51,6 +53,8 @@ public class PayOrderController { private PayOrderService orderService; @Resource private PayAppService appService; + @Resource + private PayWalletService payWalletService; @GetMapping("/get") @Operation(summary = "获得支付订单") @@ -92,11 +96,11 @@ public class PayOrderController { public CommonResult submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { // 1. 钱包支付事,需要额外传 user_id 和 user_type if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) { - Map channelExtras = reqVO.getChannelExtras() == null ? - Maps.newHashMapWithExpectedSize(2) : reqVO.getChannelExtras(); - channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(getLoginUserId())); - channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(getLoginUserType())); - reqVO.setChannelExtras(channelExtras); + if (reqVO.getChannelExtras() == null) { + reqVO.setChannelExtras(Maps.newHashMapWithExpectedSize(1)); + } + PayWalletDO wallet = payWalletService.getOrCreateWallet(getLoginUserId(), getLoginUserType()); + reqVO.getChannelExtras().put(WalletPayClient.WALLET_ID_KEY, String.valueOf(wallet.getId())); } // 2. 提交支付 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java index 7a8bb89870..1af25d3575 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java @@ -9,9 +9,11 @@ import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqV import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; import com.google.common.collect.Maps; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -22,7 +24,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -39,6 +40,8 @@ public class AppPayOrderController { @Resource private PayOrderService payOrderService; + @Resource + private PayWalletService payWalletService; @GetMapping("/get") @Operation(summary = "获得支付订单") @@ -63,11 +66,11 @@ public class AppPayOrderController { public CommonResult submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) { // 1. 钱包支付事,需要额外传 user_id 和 user_type if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) { - Map channelExtras = reqVO.getChannelExtras() == null ? - Maps.newHashMapWithExpectedSize(2) : reqVO.getChannelExtras(); - channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(getLoginUserId())); - channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(getLoginUserType())); - reqVO.setChannelExtras(channelExtras); + if (reqVO.getChannelExtras() == null) { + reqVO.setChannelExtras(Maps.newHashMapWithExpectedSize(1)); + } + PayWalletDO wallet = payWalletService.getOrCreateWallet(getLoginUserId(), getLoginUserType()); + reqVO.getChannelExtras().put(WalletPayClient.WALLET_ID_KEY, String.valueOf(wallet.getId())); } // 2. 提交支付 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index 4e7c90e937..a3ee56c6e8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -53,6 +53,10 @@ public interface PayTransferMapper extends BaseMapperX { PayTransferDO::getNo, no); } + default PayTransferDO selectByNo(String no) { + return selectOne(PayTransferDO::getNo, no); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java index d9a6511aae..933c2a1617 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java @@ -14,13 +14,16 @@ import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService; import lombok.extern.slf4j.Slf4j; @@ -39,13 +42,14 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.REFUND_NOT_FO @Slf4j public class WalletPayClient extends AbstractPayClient { - public static final String USER_ID_KEY = "user_id"; - public static final String USER_TYPE_KEY = "user_type"; + public static final String WALLET_ID_KEY = "walletId"; private PayWalletService wallService; private PayWalletTransactionService walletTransactionService; + private PayOrderService orderService; private PayRefundService refundService; + private PayTransferService transferService; public WalletPayClient(Long channelId, NonePayClientConfig config) { super(channelId, PayChannelEnum.WALLET.getCode(), config); @@ -62,19 +66,18 @@ public class WalletPayClient extends AbstractPayClient { } @Override + @SuppressWarnings("PatternVariableCanBeUsed") protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { try { - Long userId = MapUtil.getLong(reqDTO.getChannelExtras(), USER_ID_KEY); - Integer userType = MapUtil.getInt(reqDTO.getChannelExtras(), USER_TYPE_KEY); - Assert.notNull(userId, "用户 id 不能为空"); - Assert.notNull(userType, "用户类型不能为空"); - PayWalletTransactionDO transaction = wallService.orderPay(userId, userType, reqDTO.getOutTradeNo(), - reqDTO.getPrice()); + Long walletId = MapUtil.getLong(reqDTO.getChannelExtras(), WALLET_ID_KEY); + Assert.notNull(walletId, "钱包编号"); + PayWalletTransactionDO transaction = wallService.orderPay(walletId, + reqDTO.getOutTradeNo(), reqDTO.getPrice()); return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), transaction.getCreateTime(), reqDTO.getOutTradeNo(), transaction); } catch (Throwable ex) { - log.error("[doUnifiedOrder] 失败", ex); + log.error("[doUnifiedOrder][reqDTO({}) 异常]", reqDTO, ex); Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); if (ex instanceof ServiceException) { @@ -122,6 +125,7 @@ public class WalletPayClient extends AbstractPayClient { } @Override + @SuppressWarnings("PatternVariableCanBeUsed") protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { try { PayWalletTransactionDO payWalletTransaction = wallService.orderRefund(reqDTO.getOutRefundNo(), @@ -129,7 +133,7 @@ public class WalletPayClient extends AbstractPayClient { return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreateTime(), reqDTO.getOutRefundNo(), payWalletTransaction); } catch (Throwable ex) { - log.error("[doUnifiedRefund] 失败", ex); + log.error("[doUnifiedRefund][reqDOT({}) 异常]", reqDTO, ex); Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); if (ex instanceof ServiceException) { @@ -177,18 +181,71 @@ public class WalletPayClient extends AbstractPayClient { } @Override - protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) { - throw new UnsupportedOperationException("未实现"); + @SuppressWarnings("PatternVariableCanBeUsed") + public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + try { + Long walletId = Long.parseLong(reqDTO.getUserAccount()); + PayWalletTransactionDO transaction = wallService.addWalletBalance(walletId, String.valueOf(reqDTO.getOutTransferNo()), + PayWalletBizTypeEnum.TRANSFER, reqDTO.getPrice()); + return PayTransferRespDTO.successOf(transaction.getNo(), transaction.getCreateTime(), + reqDTO.getOutTransferNo(), transaction); + } catch (Throwable ex) { + log.error("[doUnifiedTransfer][reqDTO({}) 异常]", reqDTO, ex); + Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); + String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); + if (ex instanceof ServiceException) { + ServiceException serviceException = (ServiceException) ex; + errorCode = serviceException.getCode(); + errorMsg = serviceException.getMessage(); + } + return PayTransferRespDTO.closedOf(String.valueOf(errorCode), errorMsg, + reqDTO.getOutTransferNo(), ""); + } } @Override - public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { - throw new UnsupportedOperationException("待实现"); + protected PayTransferRespDTO doParseTransferNotify(Map params, String body, Map headers) { + throw new UnsupportedOperationException("钱包支付无转账回调"); } @Override protected PayTransferRespDTO doGetTransfer(String outTradeNo) { - throw new UnsupportedOperationException("待实现"); + if (transferService == null) { + transferService = SpringUtil.getBean(PayTransferService.class); + } + // 获取转账单 + PayTransferDO transfer = transferService.getTransferByNo(outTradeNo); + // 转账单不存在,返回关闭状态 + if (transfer == null) { + return PayTransferRespDTO.closedOf(String.valueOf(PAY_ORDER_EXTENSION_NOT_FOUND.getCode()), + PAY_ORDER_EXTENSION_NOT_FOUND.getMsg(), outTradeNo, ""); + } + // 关闭状态 + if (PayTransferStatusRespEnum.isClosed(transfer.getStatus())) { + return PayTransferRespDTO.closedOf(transfer.getChannelErrorCode(), + transfer.getChannelErrorMsg(), outTradeNo, ""); + } + // 成功状态 + if (PayTransferStatusRespEnum.isSuccess(transfer.getStatus())) { + PayWalletTransactionDO walletTransaction = walletTransactionService.getWalletTransaction( + String.valueOf(transfer.getId()), PayWalletBizTypeEnum.TRANSFER); + Assert.notNull(walletTransaction, "转账单 {} 钱包流水不能为空", outTradeNo); + return PayTransferRespDTO.successOf(walletTransaction.getNo(), walletTransaction.getCreateTime(), + outTradeNo, walletTransaction); + } + // 处理中状态 + if (PayTransferStatusRespEnum.isProcessing(transfer.getStatus())) { + return PayTransferRespDTO.processingOf(transfer.getChannelTransferNo(), + outTradeNo, transfer); + } + // 等待状态 + if (transfer.getStatus().equals(PayTransferStatusRespEnum.WAITING.getStatus())) { + return PayTransferRespDTO.waitingOf(transfer.getChannelTransferNo(), + outTradeNo, transfer); + } + // 其它状态为无效状态 + log.error("[doGetTransfer] 转账单 {} 的状态不正确", outTradeNo); + throw new IllegalStateException(String.format("转账单[%s] 状态不正确", outTradeNo)); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 083e49a032..f562c81694 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -57,11 +57,16 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { demoTransferMapper.insert(withdraw); // 2.1 创建支付单 - Long payTransferId = payTransferApi.createTransfer(new PayTransferCreateReqDTO() + PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 .setSubject(reqVO.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 - .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName())); // 收款信息 + .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName()); // 收款信息 + if (ObjectUtil.equal(reqVO.getType(), PayDemoWithdrawTypeEnum.WECHAT.getType())) { + transferReqDTO.setChannelExtras(PayTransferCreateReqDTO.buildWeiXinChannelExtra1000( + "测试活动", "测试奖励")); + } + Long payTransferId = payTransferApi.createTransfer(transferReqDTO); // 2.2 更新转账单到 demo 示例提现单 demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(withdraw.getId()) .setPayTransferId(payTransferId)); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index fa216f8f90..6692c2ef25 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java @@ -28,6 +28,14 @@ public interface PayTransferService { */ PayTransferDO getTransfer(Long id); + /** + * 根据转账单号获取转账单 + * + * @param no 转账单号 + * @return 转账单 + */ + PayTransferDO getTransferByNo(String no); + /** * 获得转账单分页 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index a3c5f2de9e..5d1b07d7e0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -238,6 +238,11 @@ public class PayTransferServiceImpl implements PayTransferService { return transferMapper.selectById(id); } + @Override + public PayTransferDO getTransferByNo(String no) { + return transferMapper.selectByNo(no); + } + @Override public PageResult getTransferPage(PayTransferPageReqVO pageReqVO) { return transferMapper.selectPage(pageReqVO); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java index 358d149da3..6efdc92626 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java @@ -41,12 +41,11 @@ public interface PayWalletService { /** * 钱包订单支付 * - * @param userId 用户 id - * @param userType 用户类型 + * @param walletId 钱包编号 * @param outTradeNo 外部订单号 * @param price 金额 */ - PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price); + PayWalletTransactionDO orderPay(Long walletId, String outTradeNo, Integer price); /** * 钱包订单支付退款 @@ -60,8 +59,8 @@ public interface PayWalletService { /** * 扣减钱包余额 * - * @param walletId 钱包 id - * @param bizId 业务关联 id + * @param walletId 钱包编号 + * @param bizId 业务关联编号 * @param bizType 业务关联分类 * @param price 扣减金额 * @return 钱包流水 @@ -72,8 +71,8 @@ public interface PayWalletService { /** * 增加钱包余额 * - * @param walletId 钱包 id - * @param bizId 业务关联 id + * @param walletId 钱包编号 + * @param bizId 业务关联编号 * @param bizType 业务关联分类 * @param price 增加金额 * @return 钱包流水 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index 30afb437d3..0005acef63 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java @@ -81,13 +81,13 @@ public class PayWalletServiceImpl implements PayWalletService { @Override @Transactional(rollbackFor = Exception.class) - public PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price) { + public PayWalletTransactionDO orderPay(Long walletId, String outTradeNo, Integer price) { // 1. 判断支付交易拓展单是否存 PayOrderExtensionDO orderExtension = orderService.getOrderExtensionByNo(outTradeNo); if (orderExtension == null) { throw exception(PAY_ORDER_EXTENSION_NOT_FOUND); } - PayWalletDO wallet = getOrCreateWallet(userId, userType); + PayWalletDO wallet = walletMapper.selectById(walletId); // 2. 扣减余额 return reduceWalletBalance(wallet.getId(), orderExtension.getOrderId(), PAYMENT, price); } @@ -198,7 +198,7 @@ public class PayWalletServiceImpl implements PayWalletService { break; } case UPDATE_BALANCE: // 更新余额 - case BROKERAGE_WITHDRAW: // 分佣提现 + case TRANSFER: // 分佣提现 walletMapper.updateWhenAdd(payWallet.getId(), price); break; default: { diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index db43821445..1982f12735 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -58,6 +58,8 @@ public class PayTransferUnifiedReqDTO { /** * 支付渠道的额外参数 + * + * 微信支付:sceneId 和 scene_report_infos 字段,必须传递;参考 按转账场景报备背景信息 */ private Map channelExtras; diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index c9cabf7b45..3f5ff93188 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -7,6 +7,7 @@ import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.io.FileUtils; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; @@ -20,10 +21,9 @@ import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import com.github.binarywang.wxpay.bean.notify.*; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; -import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesRequest; -import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesResult; -import com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest; -import com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsRequest; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; @@ -32,8 +32,6 @@ import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Objects; @@ -463,53 +461,57 @@ public abstract class AbstractWxPayClient extends AbstractPayClient transferDetailList = Collections.singletonList( - TransferBatchesRequest.TransferDetail.newBuilder() - .outDetailNo(reqDTO.getOutTransferNo()) - .transferAmount(reqDTO.getPrice()) - .transferRemark(reqDTO.getSubject()) - .openid(reqDTO.getUserAccount()) - .build()); - // TODO @luchi:能不能我们搞个 TransferBatchesRequestX extends TransferBatchesRequest,这样更简洁一点。 - TransferBatchesRequest transferBatches = TransferBatchesRequest.newBuilder() + // 1. 构建 TransferBillsRequest 请求 + TransferBillsRequest request = TransferBillsRequest.newBuilder() .appid(this.config.getAppId()) - .outBatchNo(reqDTO.getOutTransferNo()) - .batchName(reqDTO.getSubject()) - .batchRemark(reqDTO.getSubject()) - .totalAmount(reqDTO.getPrice()) - .totalNum(transferDetailList.size()) - .transferDetailList(transferDetailList).build() - .setNotifyUrl(reqDTO.getNotifyUrl()); + .outBillNo(reqDTO.getOutTransferNo()) + .transferAmount(reqDTO.getPrice()) + .transferRemark(reqDTO.getSubject()) + .transferSceneId(reqDTO.getChannelExtras().get("sceneId")) + .openid(reqDTO.getUserAccount()) + .userName(reqDTO.getUserName()) + .transferSceneReportInfos(JsonUtils.parseArray(reqDTO.getChannelExtras().get("sceneReportInfos"), + TransferBillsRequest.TransferSceneReportInfo.class)) + .notifyUrl(reqDTO.getNotifyUrl()) + .build(); + // 特殊:微信转账,必须 0.3 元起,才允许传入姓名 + if (reqDTO.getPrice() < 30) { + request.setUserName(null); + } + // 2.1 执行请求 - TransferBatchesResult transferBatchesResult = client.getTransferService().transferBatches(transferBatches); - // 2.2 创建返回结果 - return PayTransferRespDTO.processingOf(transferBatchesResult.getBatchId(), reqDTO.getOutTransferNo(), transferBatchesResult); + try { + TransferBillsResult response = client.getTransferService().transferBills(request); + System.out.println(response); + + // 2.2 创建返回结果 + // TODO @芋艿:这里要解析下; + return PayTransferRespDTO.processingOf(response.getTransferBillNo(), reqDTO.getOutTransferNo(), response); + } catch (WxPayException e) { + log.error("[doUnifiedTransfer][转账({}) 发起微信支付异常", reqDTO, e); + String errorCode = getErrorCode(e); + String errorMessage = getErrorMessage(e); + return PayTransferRespDTO.closedOf(errorCode, errorMessage, + reqDTO.getOutTransferNo(), e.getXmlString()); + } } @Override protected PayTransferRespDTO doGetTransfer(String outTradeNo) throws WxPayException { - QueryTransferBatchesRequest request = QueryTransferBatchesRequest.newBuilder() - .outBatchNo(outTradeNo).needQueryDetail(true).offset(0).limit(20).detailStatus("ALL") - .build(); - QueryTransferBatchesResult response = client.getTransferService().transferBatchesOutBatchNo(request); - QueryTransferBatchesResult.TransferBatch transferBatch = response.getTransferBatch(); - if (Objects.equals("FINISHED", transferBatch.getBatchStatus())) { - // 明细中全部成功则成功,任一失败则失败 - if (response.getTransferDetailList().stream().allMatch(detail -> Objects.equals("SUCCESS", detail.getDetailStatus()))) { - return PayTransferRespDTO.successOf(transferBatch.getBatchId(), parseDateV3(transferBatch.getUpdateTime()), - transferBatch.getOutBatchNo(), response); - } - if (response.getTransferDetailList().stream().anyMatch(detail -> Objects.equals("FAIL", detail.getDetailStatus()))) { - return PayTransferRespDTO.closedOf(transferBatch.getBatchStatus(), transferBatch.getCloseReason(), - transferBatch.getOutBatchNo(), response); - } + // 1. 执行请求 + TransferBillsGetResult response = client.getTransferService().getBillsByTransferBillNo(outTradeNo); + + // 2. 创建返回结果 + String state = response.getState(); + if (ObjectUtils.equalsAny(state, "ACCEPTED", "PROCESSING", "WAIT_USER_CONFIRM", "TRANSFERING")) { + return PayTransferRespDTO.processingOf(response.getTransferBillNo(), response.getOutBillNo(), response); } - if (Objects.equals("CLOSED", transferBatch.getBatchStatus())) { - return PayTransferRespDTO.closedOf(transferBatch.getBatchStatus(), transferBatch.getCloseReason(), - transferBatch.getOutBatchNo(), response); + if (Objects.equals("SUCCESS", state)) { + return PayTransferRespDTO.successOf(response.getTransferBillNo(), parseDateV3(response.getUpdateTime()), + response.getOutBillNo(), response); } - return PayTransferRespDTO.processingOf(transferBatch.getBatchId(), transferBatch.getOutBatchNo(), response); + return PayTransferRespDTO.closedOf(state, response.getFailReason(), + response.getOutBillNo(), response); } // ========== 各种工具方法 ========== diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java deleted file mode 100644 index 72296daa83..0000000000 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.github.binarywang.wxpay.bean.transfer; - -import com.github.binarywang.wxpay.v3.SpecEncrypt; -import com.google.gson.annotations.SerializedName; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; -import java.util.List; - -/** - * 发起商家转账API参数 - * - * @author zhongjun - * created on 2022/6/17 - **/ -@Data -@Builder(builderMethodName = "newBuilder") -@NoArgsConstructor -@AllArgsConstructor -public class TransferBatchesRequest implements Serializable { - private static final long serialVersionUID = -2175582517588397426L; - - /** - * 直连商户的appid - */ - @SerializedName("appid") - private String appid; - - /** - * 商家批次单号 - */ - @SerializedName("out_batch_no") - private String outBatchNo; - - /** - * 批次名称 - */ - @SerializedName("batch_name") - private String batchName; - - /** - * 批次备注 - */ - @SerializedName("batch_remark") - private String batchRemark; - - /** - * 转账总金额 - */ - @SerializedName("total_amount") - private Integer totalAmount; - - /** - * 转账总笔数 - */ - @SerializedName("total_num") - private Integer totalNum; - - /** - * 转账明细列表 - */ - @SpecEncrypt - @SerializedName("transfer_detail_list") - private List transferDetailList; - - /** - * 转账场景ID - */ - @SerializedName("transfer_scene_id") - private String transferSceneId; - - /** - * 通知地址 说明:异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数。 - */ - @SerializedName("notify_url") - private String notifyUrl; - - @Data - @Builder(builderMethodName = "newBuilder") - @AllArgsConstructor - @NoArgsConstructor - public static class TransferDetail { - - /** - * 商家明细单号 - */ - @SerializedName("out_detail_no") - private String outDetailNo; - - /** - * 转账金额 - */ - @SerializedName("transfer_amount") - private Integer transferAmount; - - /** - * 转账备注 - */ - @SerializedName("transfer_remark") - private String transferRemark; - - /** - * 用户在直连商户应用下的用户标示 - */ - @SerializedName("openid") - private String openid; - - /** - * 收款用户姓名 - */ - @SpecEncrypt - @SerializedName("user_name") - private String userName; - } -} From d2b668a67673ab787d447e411f8cb7ccc433f580 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 9 May 2025 22:03:01 +0800 Subject: [PATCH 08/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E6=8F=90=E7=8E=B0=E7=A4=BA=E4=BE=8B=EF=BC=8C?= =?UTF-8?q?=E6=8B=86=E5=88=86=20create=20=E5=92=8C=20transfer=20=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E7=8A=B6=E6=80=81=EF=BC=8C=E6=9B=B4=E7=AC=A6=E5=90=88?= =?UTF-8?q?=E5=AE=9E=E9=99=85=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/transfer/dto/PayTransferRespDTO.java | 10 ++++ .../module/pay/enums/ErrorCodeConstants.java | 7 ++- .../admin/demo/PayDemoWithdrawController.http | 18 ++++-- .../admin/demo/PayDemoWithdrawController.java | 15 ++++- .../withdraw/PayDemoWithdrawCreateReqVO.java | 13 ++-- .../vo/withdraw/PayDemoWithdrawRespVO.java | 5 +- .../dataobject/demo/PayDemoWithdrawDO.java | 4 ++ .../dal/mysql/demo/PayDemoWithdrawMapper.java | 4 +- .../demo/PayDemoTransferServiceImpl.java | 60 +++++++++++++++---- .../service/demo/PayDemoWithdrawService.java | 8 +++ .../transfer/PayTransferServiceImpl.java | 24 ++++---- 11 files changed, 128 insertions(+), 40 deletions(-) diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index b8051be752..cead3232c3 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -52,5 +52,15 @@ public class PayTransferRespDTO { */ private LocalDateTime successTime; + // ========== 其它字段 ========== + + /** + * 调用渠道的错误码 + */ + private String channelErrorCode; + /** + * 调用渠道的错误提示 + */ + private String channelErrorMsg; } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 7ee41aa15a..660cc23269 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -68,9 +68,9 @@ public interface ErrorCodeConstants { ErrorCode PAY_TRANSFER_NOT_FOUND = new ErrorCode(1_007_009_001, "转账单不存在"); ErrorCode PAY_TRANSFER_CREATE_CHANNEL_NOT_MATCH = new ErrorCode(1_007_009_002, "转账发起失败,原因:两次相同转账请求的类型不匹配"); ErrorCode PAY_TRANSFER_CREATE_PRICE_NOT_MATCH = new ErrorCode(1_007_009_003, "转账发起失败,原因:两次相同转账请求的金额不匹配"); - ErrorCode PAY_TRANSFER_CREATE_MERCHANT_EXISTS = new ErrorCode(1_007_009_004, "转账发起失败,原因:该笔业务的转账已经发起,请查询转账订单相关状态"); - ErrorCode PAY_TRANSFER_STATUS_IS_NOT_WAITING = new ErrorCode(1_007_009_005, "转账单不处于待转账"); - ErrorCode PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING = new ErrorCode(1_007_009_006, "转账单不处于待转账或转账中"); + ErrorCode PAY_TRANSFER_CREATE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_007_009_004, "转账发起失败,原因:已经存在相同的转账单,且状态不是已关闭"); + ErrorCode PAY_TRANSFER_NOTIFY_FAIL_STATUS_IS_NOT_WAITING = new ErrorCode(1_007_009_006, "通知转账结果失败,原因:转账单不处于待转账"); + ErrorCode PAY_TRANSFER_NOTIFY_FAIL_STATUS_NOT_WAITING_OR_PROCESSING = new ErrorCode(1_007_009_007, "通知转账结果失败,原因:转账单不处于待转账或转账中"); // ========== 示例订单 1-007-900-000 ========== ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1_007_900_000, "示例订单不存在"); @@ -92,5 +92,6 @@ public interface ErrorCodeConstants { ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_007_901_003, "更新示例提现单状态失败,支付转账单金额不匹配"); ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS = new ErrorCode(1_007_901_004, "更新示例提现单状态失败,支付转账单商户订单号不匹配"); ErrorCode DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH = new ErrorCode(1_007_901_005, "更新示例提现单状态失败,支付转账单渠道不匹配"); + ErrorCode DEMO_WITHDRAW_TRANSFER_FAIL_STATUS_NOT_WAITING_OR_CLOSED = new ErrorCode(1_007_901_008, "发起转账失败,原因:示例提现单状态不是【等待提现】或【提现关闭】"); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http index fa18693cf2..21255745f1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http @@ -1,4 +1,4 @@ -### 请求 /pay/pay/demo-order 接口(支付宝) => 成功 +### 请求 /pay/demo-withdraw/create 接口(支付宝) => 成功 POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -12,7 +12,7 @@ tenant-id: {{adminTenantId}} "userName": "oespxk7368" } -### 请求 /pay/pay/demo-order 接口(微信余额) => 成功 +### 请求 /pay/demo-withdraw/create 接口(微信余额) => 成功 POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -26,7 +26,7 @@ tenant-id: {{adminTenantId}} "userName": "芋艿" } -### 请求 /pay/pay/demo-order 接口(钱包余额) => 成功 +### 请求 /pay/demo-withdraw/create 接口(钱包余额) => 成功 POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -37,4 +37,14 @@ tenant-id: {{adminTenantId}} "subject": "测试转账", "price": 1, "userAccount": "1" -} \ No newline at end of file +} + +### 请求 /pay/demo-withdraw/transfer 接口(发起转账) => 成功 +POST {{baseUrl}}/pay/demo-withdraw/transfer?id=1 +Authorization: Bearer {{token}} +tenant-id: {{adminTenantId}} + +### 请求 /pay/demo-withdraw/page 接口(查询分页) => 成功 +GET {{baseUrl}}/pay/demo-withdraw/page?pageNo=1&pageSize=10 +Authorization: Bearer {{token}} +tenant-id: {{adminTenantId}} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index 02847a3363..f14aa5cc12 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWith import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; import cn.iocoder.yudao.module.pay.service.demo.PayDemoWithdrawService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.annotation.security.PermitAll; @@ -30,14 +31,22 @@ public class PayDemoWithdrawController { @PostMapping("/create") @Operation(summary = "创建示例提现单") - public CommonResult createDemoTransfer(@Valid @RequestBody PayDemoWithdrawCreateReqVO createReqVO) { + public CommonResult createDemoWithdraw(@Valid @RequestBody PayDemoWithdrawCreateReqVO createReqVO) { Long id = demoWithdrawService.createDemoWithdraw(createReqVO); return success(id); } + @PostMapping("/transfer") + @Operation(summary = "提现单转账") + @Parameter(name = "id", required = true, description = "提现单编号", example = "1024") + public CommonResult transferDemoWithdraw(@RequestParam("id") Long id) { + Long payTransferId = demoWithdrawService.transferDemoWithdraw(id); + return success(payTransferId); + } + @GetMapping("/page") @Operation(summary = "获得示例提现单分页") - public CommonResult> getDemoTransferPage(@Valid PageParam pageVO) { + public CommonResult> getDemoWithdrawPage(@Valid PageParam pageVO) { PageResult pageResult = demoWithdrawService.getDemoWithdrawPage(pageVO); return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class)); } @@ -45,7 +54,7 @@ public class PayDemoWithdrawController { @PostMapping("/update-status") @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 - public CommonResult updateDemoTransferStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { + public CommonResult updateDemoWithdrawStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { demoWithdrawService.updateDemoWithdrawStatus(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); return success(true); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java index de03533648..3c6c1c838a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawCreateReqVO.java @@ -1,12 +1,10 @@ package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.pay.enums.demo.PayDemoWithdrawTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.*; import lombok.Data; @Schema(description = "管理后台 - 示例提现单创建 Request VO") @@ -34,4 +32,11 @@ public class PayDemoWithdrawCreateReqVO { @InEnum(PayDemoWithdrawTypeEnum.class) private Integer type; + @AssertTrue(message = "收款人姓名") + public boolean isUserNameValid() { + // 特殊:支付宝必须填写用户名!!! + return ObjectUtil.notEqual(type, PayDemoWithdrawTypeEnum.ALIPAY.getType()) + || ObjectUtil.isNotEmpty(userName); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java index c99467b6a1..3abc607fe9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/withdraw/PayDemoWithdrawRespVO.java @@ -35,10 +35,13 @@ public class PayDemoWithdrawRespVO { @Schema(description = "转账单编号", example = "23695") private Long payTransferId; - @Schema(description = "转账渠道") + @Schema(description = "转账渠道", example = "wx_lite") private String transferChannelCode; @Schema(description = "转账成功时间") private LocalDateTime transferTime; + @Schema(description = "转账失败原因", example = "IP 不正确") + private String transferErrorMsg; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java index af38cadaa9..71d803c02f 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java @@ -76,5 +76,9 @@ public class PayDemoWithdrawDO extends BaseDO { * 转账成功时间 */ private LocalDateTime transferTime; + /** + * 转账错误提示 + */ + private String transferErrorMsg; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java index a1078d7805..393c161cd4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoWithdrawMapper.java @@ -15,10 +15,10 @@ public interface PayDemoWithdrawMapper extends BaseMapperX { .orderByDesc(PayDemoWithdrawDO::getId)); } - default int updateByIdAndStatus(Long id, Integer status, PayDemoWithdrawDO updateObj) { + default int updateByIdAndStatus(Long id, Integer whereStatus, PayDemoWithdrawDO updateObj) { return update(updateObj, new LambdaQueryWrapperX() .eq(PayDemoWithdrawDO::getId, id) - .eq(PayDemoWithdrawDO::getStatus, status)); + .eq(PayDemoWithdrawDO::getStatus, whereStatus)); } } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index f562c81694..9fc70aed55 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.pay.service.demo; +import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -50,27 +51,58 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { @Override public Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO reqVO) { - // 1. 保存示例提现单 PayDemoWithdrawDO withdraw = BeanUtils.toBean(reqVO, PayDemoWithdrawDO.class) .setTransferChannelCode(getTransferChannelCode(reqVO.getType())) - .setStatus(PayTransferStatusEnum.WAITING.getStatus()); + .setStatus(PayDemoWithdrawStatusEnum.WAITING.getStatus()); demoTransferMapper.insert(withdraw); + return withdraw.getId(); + } + + @Override + public Long transferDemoWithdraw(Long id) { + // 1.1 校验提现单 + PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id); + // 1.2 特殊:如果是转账失败的情况,需要充值下 + if (PayDemoWithdrawStatusEnum.isClosed(withdraw.getStatus())) { + int updateCount = demoTransferMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), + new PayDemoWithdrawDO().setStatus(PayDemoWithdrawStatusEnum.WAITING.getStatus()).setTransferErrorMsg("")); + if (updateCount == 0) { + throw exception(DEMO_WITHDRAW_TRANSFER_FAIL_STATUS_NOT_WAITING_OR_CLOSED); + } + withdraw.setStatus(PayDemoWithdrawStatusEnum.WAITING.getStatus()); + } // 2.1 创建支付单 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 - .setSubject(reqVO.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 - .setUserAccount(reqVO.getUserAccount()).setUserName(reqVO.getUserName()); // 收款信息 - if (ObjectUtil.equal(reqVO.getType(), PayDemoWithdrawTypeEnum.WECHAT.getType())) { + .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 + .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息 + if (ObjectUtil.equal(withdraw.getType(), PayDemoWithdrawTypeEnum.WECHAT.getType())) { + // 注意:微信很特殊!提现需要写明用途!!! transferReqDTO.setChannelExtras(PayTransferCreateReqDTO.buildWeiXinChannelExtra1000( "测试活动", "测试奖励")); } Long payTransferId = payTransferApi.createTransfer(transferReqDTO); - // 2.2 更新转账单到 demo 示例提现单 - demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(withdraw.getId()) - .setPayTransferId(payTransferId)); - return withdraw.getId(); + + // 2.2 更新转账单到 demo 示例提现单,并将状态更新为转账中 + demoTransferMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), + new PayDemoWithdrawDO().setPayTransferId(payTransferId)); + return payTransferId; + } + + private PayDemoWithdrawDO validateDemoWithdrawCanTransfer(Long id) { + // 校验存在 + PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id); + if (withdraw == null) { + throw exception(DEMO_WITHDRAW_NOT_FOUND); + } + // 校验状态,只有等待中或转账失败的订单,才能发起转账 + if (!PayDemoWithdrawStatusEnum.isWaiting(withdraw.getStatus()) + && !PayDemoWithdrawStatusEnum.isClosed(withdraw.getStatus())) { + throw exception(DEMO_WITHDRAW_TRANSFER_FAIL_STATUS_NOT_WAITING_OR_CLOSED); + } + return withdraw; } private String getTransferChannelCode(Integer type) { @@ -116,10 +148,12 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { PayTransferRespDTO payTransfer = validateDemoTransferStatusCanUpdate(withdraw, payTransferId); // 3. 更新示例订单状态 - demoTransferMapper.updateById(new PayDemoWithdrawDO().setId(id) - .setPayTransferId(payTransferId) - .setStatus(payTransfer.getStatus()) - .setTransferTime(payTransfer.getSuccessTime())); + Integer newStatus = PayTransferStatusEnum.isSuccess(payTransfer.getStatus()) ? PayDemoWithdrawStatusEnum.SUCCESS.getStatus() : + PayTransferStatusEnum.isClosed(payTransfer.getStatus()) ? PayDemoWithdrawStatusEnum.CLOSED.getStatus() : null; + Assert.notNull(newStatus, "转账单状态({}) 不合法", payTransfer.getStatus()); + demoTransferMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), + new PayDemoWithdrawDO().setStatus(newStatus).setTransferTime(payTransfer.getSuccessTime()) + .setTransferErrorMsg(payTransfer.getChannelErrorMsg())); } private PayTransferRespDTO validateDemoTransferStatusCanUpdate(PayDemoWithdrawDO withdraw, Long payTransferId) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java index 48af5d038b..06f2e0ecdf 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java @@ -22,6 +22,14 @@ public interface PayDemoWithdrawService { */ Long createDemoWithdraw(@Valid PayDemoWithdrawCreateReqVO createReqVO); + /** + * 提现单转账 + * + * @param id 提现单编号 + * @return 转账编号 + */ + Long transferDemoWithdraw(Long id); + /** * 获得示例提现单分页 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 5d1b07d7e0..677d5c657c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -75,7 +75,7 @@ public class PayTransferServiceImpl implements PayTransferService { // 1.3 校验转账单已经发起过转账 PayTransferDO transfer = validateTransferCanCreate(reqDTO, payApp.getId()); - // 2. 不存在创建转账单,否则允许使用相同的 no 再次发起转账 + // 2.1 情况一:不存在创建转账单,则进行创建 if (transfer == null) { String no = noRedisDAO.generate(TRANSFER_NO_PREFIX); transfer = BeanUtils.toBean(reqDTO, PayTransferDO.class) @@ -83,6 +83,10 @@ public class PayTransferServiceImpl implements PayTransferService { .setNo(no).setStatus(PayTransferStatusEnum.WAITING.getStatus()) .setNotifyUrl(payApp.getTransferNotifyUrl()); transferMapper.insert(transfer); + } else { + // 2.2 情况二:存在创建转账单,但是状态为关闭,则更新为等待中 + transferMapper.updateByIdAndStatus(transfer.getId(), transfer.getStatus(), + new PayTransferDO().setStatus(PayTransferStatusEnum.WAITING.getStatus())); } try { // 3. 调用三方渠道发起转账 @@ -114,9 +118,9 @@ public class PayTransferServiceImpl implements PayTransferService { private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantOrderId()); if (transfer != null) { - // 已经存在,并且状态不为等待状态:说明已经调用渠道转账并返回结果 - if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { - throw exception(PAY_TRANSFER_CREATE_MERCHANT_EXISTS); + // 只有转账单状态为关闭,才能再次发起转账 + if (!PayTransferStatusEnum.isClosed(transfer.getStatus())) { + throw exception(PAY_TRANSFER_CREATE_FAIL_STATUS_NOT_CLOSED); } // 校验参数是否一致 if (ObjectUtil.notEqual(reqDTO.getPrice(), transfer.getPrice())) { @@ -160,7 +164,7 @@ public class PayTransferServiceImpl implements PayTransferService { return; } if (!PayTransferStatusEnum.isWaiting(transfer.getStatus())) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_IS_NOT_WAITING); } // 2. 更新状态 @@ -168,7 +172,7 @@ public class PayTransferServiceImpl implements PayTransferService { PayTransferStatusEnum.WAITING.getStatus(), new PayTransferDO().setStatus(PayTransferStatusEnum.PROCESSING.getStatus())); if (updateCounts == 0) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_IS_NOT_WAITING); } log.info("[notifyTransferProgressing][transfer({}) 更新为转账进行中状态]", transfer.getId()); } @@ -184,7 +188,7 @@ public class PayTransferServiceImpl implements PayTransferService { return; } if (!PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_NOT_WAITING_OR_PROCESSING); } // 2. 更新状态 @@ -195,7 +199,7 @@ public class PayTransferServiceImpl implements PayTransferService { .setChannelTransferNo(notify.getChannelTransferNo()) .setChannelNotifyData(JsonUtils.toJsonString(notify))); if (updateCounts == 0) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_NOT_WAITING_OR_PROCESSING); } log.info("[notifyTransferSuccess][transfer({}) 更新为已转账]", transfer.getId()); @@ -214,7 +218,7 @@ public class PayTransferServiceImpl implements PayTransferService { return; } if (!PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_NOT_WAITING_OR_PROCESSING); } // 2. 更新状态 @@ -225,7 +229,7 @@ public class PayTransferServiceImpl implements PayTransferService { .setChannelNotifyData(JsonUtils.toJsonString(notify)) .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg())); if (updateCount == 0) { - throw exception(PAY_TRANSFER_STATUS_IS_NOT_WAITING_OR_PROCESSING); + throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_NOT_WAITING_OR_PROCESSING); } log.info("[notifyTransferClosed][transfer({}) 更新为关闭状态]", transfer.getId()); From 423c0b7ea7ca2dcf938c80207c6a4a6a39f93a21 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 May 2025 10:07:11 +0800 Subject: [PATCH 09/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90MALL=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E4=BD=A3=E9=87=91=E6=8F=90=E7=8E=B0=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A=20API=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=89=93=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 6 + .../brokerage/BrokerageWithdrawTypeEnum.java | 8 +- .../BrokerageWithdrawController.java | 7 +- .../vo/withdraw/BrokerageWithdrawBaseVO.java | 8 +- .../withdraw/BrokerageWithdrawPageReqVO.java | 4 +- .../AppBrokerageWithdrawCreateReqVO.java | 41 +++-- .../brokerage/BrokerageWithdrawDO.java | 48 ++++- .../brokerage/BrokerageWithdrawMapper.java | 4 +- .../BrokerageWithdrawServiceImpl.java | 168 ++++++++++++------ .../BrokerageWithdrawServiceImplTest.java | 12 +- .../module/pay/api/wallet/PayWalletApi.java | 10 ++ .../pay/api/wallet/dto/PayWalletRespDTO.java | 52 ++++++ .../pay/api/wallet/PayWalletApiImpl.java | 8 + .../admin/demo/PayDemoWithdrawController.http | 10 +- .../admin/demo/PayDemoWithdrawController.java | 6 +- .../demo/PayDemoTransferServiceImpl.java | 2 +- .../service/demo/PayDemoWithdrawService.java | 2 +- 17 files changed, 285 insertions(+), 111 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 1e65aec629..05e1dc1f2f 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -101,5 +101,11 @@ public interface ErrorCodeConstants { ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中"); ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元"); ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元"); + ErrorCode BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND = new ErrorCode(1_011_008_004, "提现失败,原因:用户未绑定微信"); + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_011_008_005, "提现单更新转账状态失败,转账单不匹配"); + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_011_008_006, "提现单更新转账状态失败,转账单状态不是成功或关闭状态"); + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_011_008_007, "提现单更新转账状态失败,转账单金额不匹配"); + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS = new ErrorCode(1_011_008_008, "提现单更新转账状态失败,转账单的商户订单不匹配"); + ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH = new ErrorCode(1_011_008_009, "提现单更新转账状态失败,转账渠道不匹配"); } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java index b374566d39..01aee8acde 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.enums.brokerage; import cn.iocoder.yudao.framework.common.core.ArrayValuable; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,9 +18,10 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable { WALLET(1, "钱包"), BANK(2, "银行卡"), - WECHAT(3, "微信"), // 手动打款 - ALIPAY(4, "支付宝"), + WECHAT_QR(3, "微信收款码"), // 手动打款 + ALIPAY_QR(4, "支付宝收款码"), // 手动打款 WECHAT_API(5, "微信零钱"), // 自动打款,通过微信转账 API + ALIPAY_API(6, "支付宝余额"), // 自动打款,通过支付宝转账 API ; public static final Integer[] ARRAYS = Arrays.stream(values()).map(BrokerageWithdrawTypeEnum::getType).toArray(Integer[]::new); @@ -45,7 +47,7 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable { * @return 是否 */ public static boolean isApi(Integer type) { - return WECHAT_API.getType().equals(type); + return ObjectUtils.equalsAny(type, WALLET.getType(), ALIPAY_API.getType(), WECHAT_API.getType()); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index fd7e475fed..dc0ce5ca4a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -82,10 +82,9 @@ public class BrokerageWithdrawController { return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap)); } - // TODO @luchi:update-transferred,url 改成这个。和 update-paid 、update-refunded 保持一致 - @PostMapping("/update-transfer") - @Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob - @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 + @PostMapping("/update-transferred") + @Operation(summary = "更新佣金提现的转账结果") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @PermitAll // 无需登录,安全由 BrokerageWithdrawService 内部校验实现 public CommonResult updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); brokerageWithdrawService.updateBrokerageWithdrawTransferred( diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java index 69765a5287..46e63b25b2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java @@ -37,10 +37,10 @@ public class BrokerageWithdrawBaseVO { private Integer type; @Schema(description = "真实姓名", example = "赵六") - private String name; + private String userName; - @Schema(description = "账号", example = "88677912132") - private String accountNo; + @Schema(description = "收款账号", example = "88677912132") + private String userAccount; @Schema(description = "银行名称", example = "1") private String bankName; @@ -49,7 +49,7 @@ public class BrokerageWithdrawBaseVO { private String bankAddress; @Schema(description = "收款码", example = "https://www.iocoder.cn") - private String accountQrCodeUrl; + private String qrCodeUrl; @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "状态不能为空") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawPageReqVO.java index b18ff74af4..1b5e942235 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawPageReqVO.java @@ -28,10 +28,10 @@ public class BrokerageWithdrawPageReqVO extends PageParam { private Integer type; @Schema(description = "真实姓名", example = "赵六") - private String name; + private String userName; @Schema(description = "账号", example = "886779132") - private String accountNo; + private String userAccount; @Schema(description = "银行名称", example = "1") private String bankName; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java index 83d473825e..377731b6dc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java @@ -25,23 +25,18 @@ public class AppBrokerageWithdrawCreateReqVO { @NotNull(message = "提现金额不能为空") private Integer price; - // ========== 银行卡、微信、支付宝 提现相关字段 ========== - @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") - @NotBlank(message = "提现账号不能为空", groups = {Bank.class, Wechat.class, Alipay.class}) - private String accountNo; + @NotBlank(message = "提现账号不能为空", groups = {Bank.class, WechatApi.class, AlipayApi.class}) + private String userAccount; - // ========== 微信、支付宝 提现相关字段 ========== + @Schema(description = "提现姓名", example = "张三") + @NotBlank(message = "提现姓名不能为空", groups = {Bank.class, WechatApi.class, AlipayApi.class}) + private String userName; @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png") - @URL(message = "收款码的图片,必须是一个 URL") - private String accountQrCodeUrl; + @URL(message = "收款码的图片,必须是一个 URL", groups = {WechatQR.class, AlipayQR.class}) + private String qrCodeUrl; - // ========== 银行卡 提现相关字段 ========== - - @Schema(description = "持卡人姓名", example = "张三") - @NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class}) - private String name; @Schema(description = "提现银行", example = "1") @NotNull(message = "提现银行不能为空", groups = {Bank.class}) private String bankName; @@ -54,10 +49,16 @@ public class AppBrokerageWithdrawCreateReqVO { public interface Bank { } - public interface Wechat { + public interface WechatQR { } - public interface Alipay { + public interface WechatApi { + } + + public interface AlipayQR { + } + + public interface AlipayApi { } public void validate(Validator validator) { @@ -65,10 +66,14 @@ public class AppBrokerageWithdrawCreateReqVO { ValidationUtils.validate(validator, this, Wallet.class); } else if (BrokerageWithdrawTypeEnum.BANK.getType().equals(type)) { ValidationUtils.validate(validator, this, Bank.class); - } else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(type)) { - ValidationUtils.validate(validator, this, Wechat.class); - } else if (BrokerageWithdrawTypeEnum.ALIPAY.getType().equals(type)) { - ValidationUtils.validate(validator, this, Alipay.class); + } else if (BrokerageWithdrawTypeEnum.WECHAT_QR.getType().equals(type)) { + ValidationUtils.validate(validator, this, WechatQR.class); + } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(type)) { + ValidationUtils.validate(validator, this, WechatApi.class); + } else if (BrokerageWithdrawTypeEnum.ALIPAY_QR.getType().equals(type)) { + ValidationUtils.validate(validator, this, AlipayQR.class); + } else if (BrokerageWithdrawTypeEnum.ALIPAY_API.getType().equals(type)) { + ValidationUtils.validate(validator, this, AlipayApi.class); } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java index f31c238001..0b996eadb4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java @@ -57,13 +57,25 @@ public class BrokerageWithdrawDO extends BaseDO { private Integer type; /** - * 真实姓名 + * 提现姓名 + * 1. {@link BrokerageWithdrawTypeEnum#BANK}:银行开户人 + * 2. {@link BrokerageWithdrawTypeEnum#WECHAT_API}:微信真名 + * 3. {@link BrokerageWithdrawTypeEnum#ALIPAY_API}:支付宝真名 */ - private String name; + private String userName; /** - * 账号 + * 提现账号 + * 1. {@link BrokerageWithdrawTypeEnum#BANK}:银行账号 + * 2. {@link BrokerageWithdrawTypeEnum#WECHAT_API}:微信 openid + * 3. {@link BrokerageWithdrawTypeEnum#ALIPAY_API}:支付宝账号 */ - private String accountNo; + private String userAccount; + + /** + * 收款码 + */ + private String qrCodeUrl; + /** * 银行名称 */ @@ -72,10 +84,7 @@ public class BrokerageWithdrawDO extends BaseDO { * 开户地址 */ private String bankAddress; - /** - * 收款码 - */ - private String accountQrCodeUrl; + /** * 状态 *

@@ -95,4 +104,27 @@ public class BrokerageWithdrawDO extends BaseDO { */ private String remark; + // ========== 转账相关字段 ========== + + /** + * 转账单编号 + * + * 关联 {@link cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO#getId()} + */ + private Long payTransferId; + /** + * 转账渠道 + * + * 枚举 {@link cn.iocoder.yudao.module.pay.enums.PayChannelEnum} + */ + private String transferChannelCode; + /** + * 转账成功时间 + */ + private LocalDateTime transferTime; + /** + * 转账错误提示 + */ + private String transferErrorMsg; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java index 1942cc42bb..83513ef7f5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java @@ -27,8 +27,8 @@ public interface BrokerageWithdrawMapper extends BaseMapperX() .eqIfPresent(BrokerageWithdrawDO::getUserId, reqVO.getUserId()) .eqIfPresent(BrokerageWithdrawDO::getType, reqVO.getType()) - .likeIfPresent(BrokerageWithdrawDO::getName, reqVO.getName()) - .eqIfPresent(BrokerageWithdrawDO::getAccountNo, reqVO.getAccountNo()) + .likeIfPresent(BrokerageWithdrawDO::getUserName, reqVO.getUserName()) + .eqIfPresent(BrokerageWithdrawDO::getUserAccount, reqVO.getUserAccount()) .likeIfPresent(BrokerageWithdrawDO::getBankName, reqVO.getBankName()) .eqIfPresent(BrokerageWithdrawDO::getStatus, reqVO.getStatus()) .betweenIfPresent(BrokerageWithdrawDO::getCreateTime, reqVO.getCreateTime()) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 240e771cf8..ebc75fa65f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -1,19 +1,20 @@ package cn.iocoder.yudao.module.trade.service.brokerage; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; -import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; -//import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; -import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; -import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; @@ -29,6 +30,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; +import com.google.common.base.Objects; import jakarta.annotation.Resource; import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; @@ -40,10 +42,12 @@ import java.time.LocalDateTime; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_TRANSFER_NOT_FOUND; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -64,8 +68,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private TradeConfigService tradeConfigService; - @Resource - private NotifyMessageSendApi notifyMessageSendApi; @Resource private PayTransferApi payTransferApi; @Resource @@ -109,44 +111,53 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { } private void auditBrokerageWithdrawSuccess(BrokerageWithdrawDO withdraw) { - // 1.1 钱包 - if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { - payWalletApi.addWalletBalance(new PayWalletAddBalanceReqDTO() - .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) - .setBizType(PayWalletBizTypeEnum.TRANSFER.getType()).setBizId(withdraw.getId().toString()) - .setPrice(withdraw.getPrice())); - // 1.2 微信 API - } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) { - // TODO @luchi:这里,要加个转账单号的记录;另外,调用 API 转账,是立马成功,还是有延迟的哈? - Long payTransferId = createPayTransfer(withdraw); - // 1.3 剩余类型,都是手动打款,所以不处理 - } else { - // TODO 可优化:未来可以考虑,接入支付宝、银联等 API 转账,实现自动打款 - log.info("[auditBrokerageWithdrawSuccess][withdraw({}) 类型({}) 手动打款,无需处理]", withdraw.getId(), withdraw.getType()); + // 情况一:通过 API 转账 + if (BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) { + createPayTransfer(withdraw); + return; } - // 2. 非支付 API,则直接体现成功 - if (!BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) { - brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(), - new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus())); - } + // 情况二:非 API 转账(手动打款) + brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(), + new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus())); } - private Long createPayTransfer(BrokerageWithdrawDO withdraw) { - // 1.1 获取微信 openid - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId( - UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()); - // TODO @luchi:这里,需要校验非空。如果空的话,要有业务异常哈; + private void createPayTransfer(BrokerageWithdrawDO withdraw) { + // 1.1 获取基础信息 + String userAccount = withdraw.getUserAccount(); + String userName = withdraw.getUserName(); + String channelCode = null; + Map channelExtras = null; + if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.ALIPAY_API.getType())) { + channelCode = PayChannelEnum.ALIPAY_PC.getCode(); + } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType())) { + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId( + UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()); + if (socialUser == null) { + throw exception(BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND); + } + channelCode = PayChannelEnum.WX_LITE.getCode(); + userAccount = socialUser.getOpenid(); + // 特殊:微信需要有报备信息 + channelExtras = PayTransferCreateReqDTO.buildWeiXinChannelExtra1000("佣金提现", "佣金提现"); + } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WALLET.getType())) { + PayWalletRespDTO wallet = payWalletApi.getOrCreateWallet(withdraw.getUserId(), UserTypeEnum.MEMBER.getValue()); + Assert.notNull(wallet, "钱包不存在"); + channelCode = PayChannelEnum.WALLET.getCode(); + userAccount = wallet.getId().toString(); + } // 1.2 构建请求 - PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO() - .setAppKey(tradeOrderProperties.getPayAppKey()) - .setChannelCode("wx_lite") // TODO @芋艿:【转账】这里要处理下; - .setMerchantOrderId(withdraw.getId().toString()) - .setPrice(withdraw.getPrice()) - .setSubject("佣金提现") - .setUserAccount(socialUser.getOpenid()).setUserIp(getClientIP()); - // 2. 发起请求 - return payTransferApi.createTransfer(payTransferCreateReqDTO); + PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() + .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) + .setMerchantOrderId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) + .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) + .setChannelExtras(channelExtras); + // 1.3 发起请求 + Long payTransferId = payTransferApi.createTransfer(transferReqDTO); + + // 2. 更新提现记录 + brokerageWithdrawMapper.updateById(new BrokerageWithdrawDO().setId(withdraw.getId()) + .setPayTransferId(payTransferId).setTransferChannelCode(channelCode)); } private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) { @@ -220,22 +231,71 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Override @Transactional(rollbackFor = Exception.class) public void updateBrokerageWithdrawTransferred(Long id, Long payTransferId) { - BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); - PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId); - // TODO @luchi:建议参考支付那,即使成功的情况下,也要各种校验;金额是否匹配、转账单号是否匹配、是否重复调用; - if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) { - withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()); - // TODO @luchi:发送站内信 - } else if (PayTransferStatusEnum.isWaitingOrProcessing(transfer.getStatus())) { - // TODO @luchi:这里,是不是不用更新哈? - withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()); - } else { - withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus()); - // 3.2 驳回时需要退还用户佣金 - brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT, - String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle()); + // 1.1 校验提现单是否存在 + BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id); + if (withdraw == null) { + log.error("[updateBrokerageWithdrawTransferred][withdraw({}) payTransfer({}) 不存在提现单,请进行处理!]", id, payTransferId); + throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS); } - brokerageWithdrawMapper.updateById(withdraw); + // 1.2 校验提现单已经结束(成功或失败) + if (ObjectUtils.equalsAny(withdraw.getStatus(), BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus(), + BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus())) { + // 特殊:转账单编号相同,直接返回,说明重复回调 + if (ObjectUtil.equal(withdraw.getPayTransferId(), payTransferId)) { + log.warn("[updateBrokerageWithdrawTransferred][withdraw({}) 已结束,且转账单编号相同({}),直接返回]", withdraw, payTransferId); + return; + } + // 异常:转账单编号不同,说明转账单编号错误 + log.error("[updateBrokerageWithdrawTransferred][withdraw({}) 转账单不匹配({}),请进行处理!]", withdraw, payTransferId); + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR); + } + + // 2. 校验转账单的合法性 + PayTransferRespDTO payTransfer = validateBrokerageTransferStatusCanUpdate(withdraw, payTransferId); + + // 3. 更新提现单状态 + Integer newStatus = PayTransferStatusEnum.isSuccess(payTransfer.getStatus()) ? BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus() : + PayTransferStatusEnum.isClosed(payTransfer.getStatus()) ? BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus() : null; + Assert.notNull(newStatus, "转账单状态({}) 不合法", payTransfer.getStatus()); + brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), + new BrokerageWithdrawDO().setStatus(newStatus) + .setTransferTime(payTransfer.getSuccessTime()) + .setTransferErrorMsg(payTransfer.getChannelErrorMsg())); + } + + private PayTransferRespDTO validateBrokerageTransferStatusCanUpdate(BrokerageWithdrawDO withdraw, Long payTransferId) { + // 1. 校验转账单是否存在 + PayTransferRespDTO payTransfer = payTransferApi.getTransfer(payTransferId); + if (payTransfer == null) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 不存在,请进行处理!]", withdraw.getId(), payTransferId); + throw exception(PAY_TRANSFER_NOT_FOUND); + } + + // 2.1 校验转账单已成功或关闭 + if (!PayTransferStatusEnum.isSuccessOrClosed(payTransfer.getStatus())) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 未结束,请进行处理!payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED); + } + // 2.2 校验转账金额一致 + if (ObjectUtil.notEqual(payTransfer.getPrice(), withdraw.getPrice())) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账金额不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); + } + // 2.3 校验转账订单匹配 + if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); + } + // 2.4 校验转账渠道一致 + if (ObjectUtil.notEqual(payTransfer.getChannelCode(), withdraw.getTransferChannelCode())) { + log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) payTransfer({}) 转账渠道不匹配,请进行处理!withdraw 数据是:{},payTransfer 数据是:{}]", + withdraw.getId(), payTransferId, JsonUtils.toJsonString(withdraw), JsonUtils.toJsonString(payTransfer)); + throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_CHANNEL_NOT_MATCH); + } + return payTransfer; } @Override diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java index c6dd0e3b2f..386a7dd6c0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java @@ -56,8 +56,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { BrokerageWithdrawDO dbBrokerageWithdraw = randomPojo(BrokerageWithdrawDO.class, o -> { // 等会查询到 o.setUserId(null); o.setType(null); - o.setName(null); - o.setAccountNo(null); + o.setUserName(null); + o.setUserAccount(null); o.setBankName(null); o.setStatus(null); o.setCreateTime(null); @@ -68,9 +68,9 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { // 测试 type 不匹配 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setType(null))); // 测试 name 不匹配 - brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setName(null))); + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserName(null))); // 测试 accountNo 不匹配 - brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAccountNo(null))); + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserAccount(null))); // 测试 bankName 不匹配 brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setBankName(null))); // 测试 status 不匹配 @@ -87,8 +87,8 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { BrokerageWithdrawPageReqVO reqVO = new BrokerageWithdrawPageReqVO(); reqVO.setUserId(null); reqVO.setType(null); - reqVO.setName(null); - reqVO.setAccountNo(null); + reqVO.setUserName(null); + reqVO.setUserAccount(null); reqVO.setBankName(null); reqVO.setStatus(null); reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java index bf6f1bc7ec..5586929ab5 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.pay.api.wallet; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; /** * 钱包 API 接口 @@ -16,4 +17,13 @@ public interface PayWalletApi { */ void addWalletBalance(PayWalletAddBalanceReqDTO reqDTO); + /** + * 获取钱包信息 + * + * @param userId 用户编号 + * @param userType 用户类型 + * @return 钱包信息 + */ + PayWalletRespDTO getOrCreateWallet(Long userId, Integer userType); + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java new file mode 100644 index 0000000000..9a8db79768 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletRespDTO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.pay.api.wallet.dto; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import lombok.Data; + +/** + * 钱包 Response DTO + * + * @author jason + */ +@Data +public class PayWalletRespDTO { + + /** + * 编号 + */ + private Long id; + + /** + * 用户 id + * + * 关联 MemberUserDO 的 id 编号 + * 关联 AdminUserDO 的 id 编号 + */ + private Long userId; + /** + * 用户类型, 预留 多商户转帐可能需要用到 + * + * 关联 {@link UserTypeEnum} + */ + private Integer userType; + + /** + * 余额,单位分 + */ + private Integer balance; + + /** + * 冻结金额,单位分 + */ + private Integer freezePrice; + + /** + * 累计支出,单位分 + */ + private Integer totalExpense; + /** + * 累计充值,单位分 + */ + private Integer totalRecharge; + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java index 98e4a952b6..627cb5c135 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.pay.api.wallet; import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; @@ -30,4 +32,10 @@ public class PayWalletApiImpl implements PayWalletApi { payWalletService.addWalletBalance(wallet.getId(), reqDTO.getBizId(), bizType, reqDTO.getPrice()); } + @Override + public PayWalletRespDTO getOrCreateWallet(Long userId, Integer userType) { + PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); + return BeanUtils.toBean(wallet, PayWalletRespDTO.class); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http index 21255745f1..4162baad1b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.http @@ -1,4 +1,4 @@ -### 请求 /pay/demo-withdraw/create 接口(支付宝) => 成功 +### 请求 /pay/demo-withdraw/create 接口(支付宝) POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -12,7 +12,7 @@ tenant-id: {{adminTenantId}} "userName": "oespxk7368" } -### 请求 /pay/demo-withdraw/create 接口(微信余额) => 成功 +### 请求 /pay/demo-withdraw/create 接口(微信余额) POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -26,7 +26,7 @@ tenant-id: {{adminTenantId}} "userName": "芋艿" } -### 请求 /pay/demo-withdraw/create 接口(钱包余额) => 成功 +### 请求 /pay/demo-withdraw/create 接口(钱包余额) POST {{baseUrl}}/pay/demo-withdraw/create Authorization: Bearer {{token}} Content-Type: application/json @@ -39,12 +39,12 @@ tenant-id: {{adminTenantId}} "userAccount": "1" } -### 请求 /pay/demo-withdraw/transfer 接口(发起转账) => 成功 +### 请求 /pay/demo-withdraw/transfer 接口(发起转账) POST {{baseUrl}}/pay/demo-withdraw/transfer?id=1 Authorization: Bearer {{token}} tenant-id: {{adminTenantId}} -### 请求 /pay/demo-withdraw/page 接口(查询分页) => 成功 +### 请求 /pay/demo-withdraw/page 接口(查询分页) GET {{baseUrl}}/pay/demo-withdraw/page?pageNo=1&pageSize=10 Authorization: Bearer {{token}} tenant-id: {{adminTenantId}} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index f14aa5cc12..251ec35ce7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -51,11 +51,11 @@ public class PayDemoWithdrawController { return success(BeanUtils.toBean(pageResult, PayDemoWithdrawRespVO.class)); } - @PostMapping("/update-status") + @PostMapping("/update-transferred") @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 - public CommonResult updateDemoWithdrawStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { - demoWithdrawService.updateDemoWithdrawStatus(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + public CommonResult updateDemoWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { + demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 9fc70aed55..29e175c2a8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -124,7 +124,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { } @Override - public void updateDemoWithdrawStatus(Long id, Long payTransferId) { + public void updateDemoWithdrawTransferred(Long id, Long payTransferId) { // 1.1 校验转账单是否存在 PayDemoWithdrawDO withdraw = demoTransferMapper.selectById(id); if (withdraw == null) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java index 06f2e0ecdf..e8a5980ad8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java @@ -43,6 +43,6 @@ public interface PayDemoWithdrawService { * @param id 编号 * @param payTransferId 转账单编号 */ - void updateDemoWithdrawStatus(Long id, Long payTransferId); + void updateDemoWithdrawTransferred(Long id, Long payTransferId); } From fe8871b5f150df9ee43d828a11da5f47685991d6 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 May 2025 11:48:29 +0800 Subject: [PATCH 10/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90MALL=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E4=BD=A3=E9=87=91=E6=8F=90=E7=8E=B0=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8F=90=E7=8E=B0=E5=A4=B1=E8=B4=A5=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=87=8D=E6=96=B0=E5=8F=91=E8=B5=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/withdraw/BrokerageWithdrawRespVO.java | 3 +++ .../mysql/brokerage/BrokerageWithdrawMapper.java | 8 ++++---- .../brokerage/BrokerageWithdrawServiceImpl.java | 13 +++++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java index 0abd77e69a..4096dd9514 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java @@ -16,6 +16,9 @@ public class BrokerageWithdrawRespVO extends BrokerageWithdrawBaseVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") private Long id; + @Schema(description = "转账错误提示", example = "余额不足") + private String transferErrorMsg; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java index 83513ef7f5..71828f7c08 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageWithdrawMapper.java @@ -28,17 +28,17 @@ public interface BrokerageWithdrawMapper extends BaseMapperX() .eq(BrokerageWithdrawDO::getId, id) - .eq(BrokerageWithdrawDO::getStatus, status)); + .eq(BrokerageWithdrawDO::getStatus, whereStatus)); } default List selectCountAndSumPriceByUserIdAndStatus(Collection userIds, diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index ebc75fa65f..4df5f3e085 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -86,15 +86,24 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { public void auditBrokerageWithdraw(Long id, BrokerageWithdrawStatusEnum status, String auditReason, String userIp) { // 1.1 校验存在 BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); + // 1.2 特殊:【重新转账】如果是提现失败,并且状态是审核中,那么更新状态为审核中,并且清空 transferErrorMsg + if (BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus().equals(withdraw.getStatus())) { + int updateCount = brokerageWithdrawMapper.updateByIdAndStatus(id, withdraw.getStatus(), + new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.AUDITING.getStatus()).setTransferErrorMsg("")); + if (updateCount == 0) { + throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); + } + withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDITING.getStatus()).setTransferErrorMsg(""); + } // 1.2 校验状态为审核中 if (ObjectUtil.notEqual(BrokerageWithdrawStatusEnum.AUDITING.getStatus(), withdraw.getStatus())) { throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); } // 2. 更新状态 - int rows = brokerageWithdrawMapper.updateByIdAndStatus(id, BrokerageWithdrawStatusEnum.AUDITING.getStatus(), + int updateCount = brokerageWithdrawMapper.updateByIdAndStatus(id, withdraw.getStatus(), new BrokerageWithdrawDO().setStatus(status.getStatus()).setAuditReason(auditReason).setAuditTime(LocalDateTime.now())); - if (rows == 0) { + if (updateCount == 0) { throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); } From 288d8e313202362438b747fb5dabe970cd214665 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 May 2025 16:43:55 +0800 Subject: [PATCH 11/19] =?UTF-8?q?reactor=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E4=BC=98=E5=8C=96=E9=80=80=E6=AC=BE=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=20mercha?= =?UTF-8?q?ntRefundId=20=E9=80=80=E6=AC=BE=E7=BC=96=E5=8F=B7=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20reactor=EF=BC=9A=E3=80=90MALL=20=E5=95=86=E5=9F=8E?= =?UTF-8?q?=E3=80=91=E5=94=AE=E5=90=8E=E9=80=80=E6=AC=BE=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=E5=9B=9E=E8=B0=83=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trade/enums/ErrorCodeConstants.java | 15 ++- .../aftersale/AfterSaleOperateTypeEnum.java | 4 +- .../admin/aftersale/AfterSaleController.java | 21 +++- .../BrokerageWithdrawController.java | 2 +- .../core/aop/AfterSaleLogAspect.java | 16 ++- .../core/utils/AfterSaleLogUtils.java | 5 + .../service/aftersale/AfterSaleService.java | 9 ++ .../aftersale/AfterSaleServiceImpl.java | 118 ++++++++++++------ .../BrokerageWithdrawServiceImpl.java | 16 +-- .../order/TradeOrderUpdateService.java | 8 ++ .../order/TradeOrderUpdateServiceImpl.java | 18 ++- .../api/notify/dto/PayRefundNotifyReqDTO.java | 6 + .../notify/dto/PayTransferNotifyReqDTO.java | 2 +- .../pay/api/refund/dto/PayRefundRespDTO.java | 15 +++ .../transfer/dto/PayTransferCreateReqDTO.java | 2 +- .../api/transfer/dto/PayTransferRespDTO.java | 2 +- .../pay/api/refund/PayRefundApiImpl.java | 11 +- .../admin/demo/PayDemoOrderController.java | 4 +- .../admin/demo/PayDemoWithdrawController.java | 2 +- .../admin/notify/PayNotifyController.java | 20 ++- .../admin/notify/vo/PayNotifyTaskBaseVO.java | 45 ------- .../notify/vo/PayNotifyTaskDetailRespVO.java | 14 +-- .../notify/vo/PayNotifyTaskPageReqVO.java | 6 + .../admin/notify/vo/PayNotifyTaskRespVO.java | 44 ++++++- .../wallet/PayWalletRechargeController.java | 7 +- .../convert/notify/PayNotifyTaskConvert.java | 43 ------- .../pay/convert/refund/PayRefundConvert.java | 3 - .../dataobject/notify/PayNotifyTaskDO.java | 10 ++ .../dataobject/transfer/PayTransferDO.java | 2 +- .../dal/mysql/notify/PayNotifyTaskMapper.java | 2 + .../dal/mysql/transfer/PayTransferMapper.java | 4 +- .../pay/service/demo/PayDemoOrderService.java | 3 +- .../service/demo/PayDemoOrderServiceImpl.java | 14 ++- .../demo/PayDemoTransferServiceImpl.java | 4 +- .../service/notify/PayNotifyServiceImpl.java | 37 ++++-- .../pay/service/refund/PayRefundService.java | 2 +- .../service/refund/PayRefundServiceImpl.java | 2 +- .../transfer/PayTransferServiceImpl.java | 2 +- .../wallet/PayWalletRechargeService.java | 12 +- .../wallet/PayWalletRechargeServiceImpl.java | 32 ++--- .../service/refund/PayRefundServiceTest.java | 16 +-- 41 files changed, 356 insertions(+), 244 deletions(-) delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index 05e1dc1f2f..b2d72e4b01 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -36,8 +36,10 @@ public interface ErrorCodeConstants { ErrorCode ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1_011_000_031, "交易订单修改收货地址失败,原因:订单不是【待发货】状态"); ErrorCode ORDER_CREATE_FAIL_EXIST_UNPAID = new ErrorCode(1_011_000_032, "交易订单创建失败,原因:存在未付款订单"); ErrorCode ORDER_CANCEL_PAID_FAIL = new ErrorCode(1_011_000_033, "交易订单取消支付失败,原因:订单不是【{}】状态"); - ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_034, "交易订单自提失败,原因:你没有核销该门店订单的权限"); - ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_035, "交易订单创建失败,原因:用户积分不足"); + ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_NOT_FOUND = new ErrorCode(1_011_000_034, "交易订单更新支付订单退款状态失败,原因:退款单不存在"); + ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_STATUS_NOT_SUCCESS = new ErrorCode(1_011_000_035, "交易订单更新支付订单退款状态失败,原因:退款单状态不是【退款成功】"); + ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_036, "交易订单自提失败,原因:你没有核销该门店订单的权限"); + ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_037, "交易订单创建失败,原因:用户积分不足"); // ========== After Sale 模块 1-011-000-100 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); @@ -51,9 +53,13 @@ public interface ErrorCodeConstants { ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1_011_000_108, "退货失败,售后单状态不处于【待买家退货】"); ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1_011_000_109, "确认收货失败,售后单状态不处于【待确认收货】"); ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1_011_000_111, "退款失败,退款单不存在"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_NOT_SUCCESS_OR_FAILURE = new ErrorCode(1_011_000_112, "退款失败,退款单未退款"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1_011_000_113, "退款失败,退款金额不匹配"); + ErrorCode AFTER_SALE_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1_011_000_114, "退款失败,退款单不匹配"); ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY = - new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_112, "订单拼团中,无法申请售后"); + new ErrorCode(1_011_000_115, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_116, "订单拼团中,无法申请售后"); // ========== Cart 模块 1-011-002-000 ========== ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在"); @@ -101,7 +107,6 @@ public interface ErrorCodeConstants { ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中"); ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元"); ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元"); - ErrorCode BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND = new ErrorCode(1_011_008_004, "提现失败,原因:用户未绑定微信"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_ID_ERROR = new ErrorCode(1_011_008_005, "提现单更新转账状态失败,转账单不匹配"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_TRANSFER_STATUS_NOT_SUCCESS_OR_CLOSED = new ErrorCode(1_011_008_006, "提现单更新转账状态失败,转账单状态不是成功或关闭状态"); ErrorCode BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_011_008_007, "提现单更新转账状态失败,转账单金额不匹配"); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java index db870c6375..5f23a5dbc9 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java @@ -19,7 +19,9 @@ public enum AfterSaleOperateTypeEnum { MEMBER_DELIVERY(20, "会员填写退货物流信息,快递公司:{deliveryName},快递单号:{logisticsNo}"), ADMIN_AGREE_RECEIVE(21, "商家收货"), ADMIN_DISAGREE_RECEIVE(22, "商家拒绝收货,原因:{reason}"), - ADMIN_REFUND(30, "商家退款"), + ADMIN_REFUND(30, "商家发起退款"), + SYSTEM_REFUND_SUCCESS(31, "退款成功"), + SYSTEM_REFUND_FAIL(32, "退款失败"), MEMBER_CANCEL(40, "会员取消退款"), ; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java index d6429b44fa..a87afb672c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; @@ -15,10 +16,12 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -46,6 +49,8 @@ public class AfterSaleController { @Resource private TradeOrderQueryService tradeOrderQueryService; @Resource + private TradeOrderUpdateService tradeOrderUpdateService; + @Resource private AfterSaleLogService afterSaleLogService; @Resource private MemberUserApi memberUserApi; @@ -133,11 +138,19 @@ public class AfterSaleController { @PostMapping("/update-refunded") @Operation(summary = "更新售后订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob - @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 - public CommonResult updateAfterRefund(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { - // 目前业务逻辑,不需要做任何事情 - // 当然,退款会有小概率会失败的情况,可以监控失败状态,进行告警 + @PermitAll // 无需登录,安全由 AfterSaleService 内部校验实现 + public CommonResult updateAfterSaleRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); + if (StrUtil.startWithAny(notifyReqDTO.getMerchantRefundId(), "order-")) { + tradeOrderUpdateService.updatePaidOrderRefunded( + Long.parseLong(notifyReqDTO.getMerchantRefundId()), + notifyReqDTO.getPayRefundId()); + } else { + afterSaleService.updateAfterSaleRefunded( + Long.parseLong(notifyReqDTO.getMerchantRefundId()), + Long.parseLong(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getPayRefundId()); + } return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index dc0ce5ca4a..8a94833d8a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -88,7 +88,7 @@ public class BrokerageWithdrawController { public CommonResult updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); brokerageWithdrawService.updateBrokerageWithdrawTransferred( - Long.parseLong(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayTransferId()); + Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java index d0d60e2c12..c56f33afbe 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/aop/AfterSaleLogAspect.java @@ -1,18 +1,20 @@ package cn.iocoder.yudao.module.trade.framework.aftersale.core.aop; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO; +import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog; import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService; import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; -import jakarta.annotation.Resource; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; @@ -50,6 +52,10 @@ public class AfterSaleLogAspect { * 操作后的状态 */ private static final ThreadLocal AFTER_STATUS = new ThreadLocal<>(); + /** + * 操作类型(仅“动态场景”需要使用) + */ + private static final ThreadLocal OPERATE_TYPE = new ThreadLocal<>(); /** * 拓展参数 Map,用于格式化操作内容 */ @@ -69,6 +75,7 @@ public class AfterSaleLogAspect { if (afterSaleId == null) { // 如果未设置,只有注解,说明不需要记录日志 return; } + AfterSaleOperateTypeEnum operateType = ObjUtil.defaultIfNull(OPERATE_TYPE.get(), afterSaleLog.operateType()); Integer beforeStatus = BEFORE_STATUS.get(); Integer afterStatus = AFTER_STATUS.get(); Map exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap()); @@ -78,7 +85,7 @@ public class AfterSaleLogAspect { AfterSaleLogCreateReqBO createBO = new AfterSaleLogCreateReqBO() .setUserId(userId).setUserType(userType) .setAfterSaleId(afterSaleId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus) - .setOperateType(afterSaleLog.operateType().getType()).setContent(content); + .setOperateType(operateType.getType()).setContent(content); afterSaleLogService.createAfterSaleLog(createBO); } catch (Exception exception) { log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception); @@ -116,6 +123,10 @@ public class AfterSaleLogAspect { EXTS.set(exts); } + public static void setAfterSaleOperateType(AfterSaleOperateTypeEnum operateType) { + OPERATE_TYPE.set(operateType); + } + public static void setUserInfo(Long userId, Integer userType) { USER_ID.set(userId); USER_TYPE.set(userType); @@ -127,6 +138,7 @@ public class AfterSaleLogAspect { AFTER_SALE_ID.remove(); BEFORE_STATUS.remove(); AFTER_STATUS.remove(); + OPERATE_TYPE.remove(); EXTS.remove(); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java index 3f9fc5d74b..14f97547bf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersale/core/utils/AfterSaleLogUtils.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.framework.aftersale.core.utils; +import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.framework.aftersale.core.aop.AfterSaleLogAspect; import java.util.Map; @@ -13,6 +14,10 @@ import java.util.Map; */ public class AfterSaleLogUtils { + public static void setAfterSaleOperateType(AfterSaleOperateTypeEnum operateType) { + AfterSaleLogAspect.setAfterSaleOperateType(operateType); + } + public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus) { setAfterSaleInfo(id, beforeStatus, afterStatus, null); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java index 486a68b7c0..d2c0c3c849 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleService.java @@ -108,6 +108,15 @@ public interface AfterSaleService { */ void refundAfterSale(Long userId, String userIp, Long id); + /** + * 更新售后订单为已退款 + * + * @param id 售后编号 + * @param orderId 订单编号 + * @param payRefundId 支付退款编号 + */ + void updateAfterSaleRefunded(Long id, Long orderId, Long payRefundId); + /** * 【会员】取消售后 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java index 915f253f0f..f0c63a032d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; @@ -41,13 +43,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** @@ -184,8 +185,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null, AfterSaleStatusEnum.APPLY.getStatus()); - - // TODO 发送售后消息 return afterSale; } @@ -206,8 +205,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); - - // TODO 发送售后消息 } @Override @@ -226,8 +223,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } @@ -281,8 +276,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), MapUtil.builder().put("deliveryName", express.getName()) .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build()); - - // TODO 发送售后消息 } @Override @@ -299,8 +292,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus()); - - // TODO 发送售后消息 } @Override @@ -326,8 +317,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleStatusEnum.SELLER_REFUSE.getStatus(), MapUtil.of("reason", refuseReqVO.getRefuseMemo())); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } @@ -365,33 +354,90 @@ public class AfterSaleServiceImpl implements AfterSaleService { // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 createPayRefund(userIp, afterSale); - // 更新售后单的状态为【已完成】 - updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() - .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); - // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), - AfterSaleStatusEnum.COMPLETE.getStatus()); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【已完成】 - tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice()); + afterSale.getStatus()); // 特殊:这里状态不变,而是最终 updateAfterSaleRefunded 处理!!! } private void createPayRefund(String userIp, AfterSaleDO afterSale) { - TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + // 创建退款单 + PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) + .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); + Long payRefundId = payRefundApi.createRefund(createReqDTO); - @Override - public void afterCommit() { - // 创建退款单 - PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) - .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); - Long payRefundId = payRefundApi.createRefund(createReqDTO); - // 更新售后单的退款单号 - tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); - } - }); + // 更新售后单的退款单号 + tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.SYSTEM_REFUND_SUCCESS) + public void updateAfterSaleRefunded(Long id, Long orderId, Long payRefundId) { + // 1. 校验售后单的状态,并状态待退款 + AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus())) { + throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); + } + + // 2. 校验退款单 + PayRefundRespDTO payRefund = validatePayRefund(afterSale, payRefundId); + + // 3. 处理退款结果 + if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { + // 【情况一:退款成功】 + updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() + .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); + + // 记录售后日志 + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.COMPLETE.getStatus()); + + // 更新交易订单项的售后状态为【已完成】 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice()); + // 【情况二:退款失败】 + } else if (PayRefundStatusEnum.isFailure(payRefund.getStatus())) { + // 记录售后日志 + AfterSaleLogUtils.setAfterSaleOperateType(AfterSaleOperateTypeEnum.SYSTEM_REFUND_FAIL); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), afterSale.getStatus()); + } + } + + /** + * 校验退款单的合法性 + * + * @param afterSale 售后单 + * @param payRefundId 退款单编号 + * @return 退款单 + */ + private PayRefundRespDTO validatePayRefund(AfterSaleDO afterSale, Long payRefundId) { + // 1. 校验退款单是否存在 + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); + if (payRefund == null) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 不存在,请进行处理!]", afterSale.getId(), payRefundId); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_FOUND); + } + // 2.1 校验退款单无退款结果(成功、失败) + if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus()) + && !PayRefundStatusEnum.isFailure(payRefund.getStatus())) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 无退款结果,请进行处理!payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_SUCCESS_OR_FAILURE); + } + // 2.2 校验退款金额一致 + if (ObjectUtil.notEqual(payRefund.getRefundPrice(), afterSale.getRefundPrice())) { + log.error("[validatePayRefund][afterSale({}) payRefund({}) 退款金额不匹配,请进行处理!afterSale 数据是:{},payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(afterSale), toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); + } + // 2.3 校验退款订单匹配(二次) + if (ObjectUtil.notEqual(payRefund.getMerchantRefundId(), afterSale.getId().toString())) { + log.error("[validatePayRefund][afterSale({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", + afterSale.getId(), payRefundId, toJsonString(payRefund)); + throw exception(AFTER_SALE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); + } + return payRefund; } @Override @@ -417,8 +463,6 @@ public class AfterSaleServiceImpl implements AfterSaleService { AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.BUYER_CANCEL.getStatus()); - // TODO 发送售后消息 - // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 4df5f3e085..353f75742b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -15,9 +15,6 @@ import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; -import cn.iocoder.yudao.module.system.api.social.SocialUserApi; -import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; -import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; @@ -71,8 +68,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private PayTransferApi payTransferApi; @Resource - private SocialUserApi socialUserApi; - @Resource private PayWalletApi payWalletApi; @Resource @@ -140,13 +135,8 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.ALIPAY_API.getType())) { channelCode = PayChannelEnum.ALIPAY_PC.getCode(); } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType())) { - SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId( - UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()); - if (socialUser == null) { - throw exception(BROKERAGE_WITHDRAW_TRANSFER_FAIL_WECHAT_NOT_BIND); - } channelCode = PayChannelEnum.WX_LITE.getCode(); - userAccount = socialUser.getOpenid(); + userAccount = withdraw.getUserAccount(); // 特殊:微信需要有报备信息 channelExtras = PayTransferCreateReqDTO.buildWeiXinChannelExtra1000("佣金提现", "佣金提现"); } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WALLET.getType())) { @@ -158,7 +148,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 1.2 构建请求 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) - .setMerchantOrderId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) + .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) .setChannelExtras(channelExtras); // 1.3 发起请求 @@ -293,7 +283,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } // 2.3 校验转账订单匹配 - if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + if (ObjectUtil.notEqual(payTransfer.getMerchantTransferId(), withdraw.getId().toString())) { log.error("[validateBrokerageTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); throw exception(BROKERAGE_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index 59ad63acfb..408857d176 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java @@ -209,6 +209,14 @@ public interface TradeOrderUpdateService { */ void cancelPaidOrder(Long userId, Long orderId, Integer cancelType); + /** + * 取消支付订单的退款回调 + * + * @param id 订单编号 + * @param payRefundId 支付退款编号 + */ + void updatePaidOrderRefunded(Long id, Long payRefundId); + /** * 更新下单赠送的优惠券编号到订单 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index 030cc34317..9a59c1ace3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -20,7 +20,9 @@ import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.system.api.social.SocialClientApi; @@ -938,10 +940,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用 .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 - .setMerchantRefundId(String.valueOf(order.getId())) + // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分 + // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法 + .setMerchantRefundId("order-" + order.getId()) .setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice())); // 价格信息 } + @Override + public void updatePaidOrderRefunded(Long id, Long payRefundId) { + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); + if (payRefund == null) { + throw exception(ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_NOT_FOUND); + } + // 特殊:因为在 cancelPaidOrder 已经进行订单的取消,所以这里必须退款成功!!! + if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { + throw exception(ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_STATUS_NOT_SUCCESS); + } + } + @Override public void updateOrderGiveCouponIds(Long userId, Long orderId, List giveCouponIds) { // 1. 检验订单存在 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java index 29e670492c..6746c319fc 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayRefundNotifyReqDTO.java @@ -25,6 +25,12 @@ public class PayRefundNotifyReqDTO { @NotEmpty(message = "商户退款单编号不能为空") private String merchantOrderId; + /** + * 商户退款编号 + */ + @NotEmpty(message = "商户退款编号不能为空") + private String merchantRefundId; + /** * 支付退款编号 */ diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java index 982a3be75b..f3a92d8da9 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/notify/dto/PayTransferNotifyReqDTO.java @@ -23,7 +23,7 @@ public class PayTransferNotifyReqDTO { * 商户转账单号 */ @NotEmpty(message = "商户转账单号不能为空") - private String merchantOrderId; + private String merchantTransferId; /** * 转账订单编号 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java index 0065cb4934..725f3911b4 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundRespDTO.java @@ -42,9 +42,24 @@ public class PayRefundRespDTO { * 商户订单编号 */ private String merchantOrderId; + /** + * 商户退款编号 + */ + private String merchantRefundId; /** * 退款成功时间 */ private LocalDateTime successTime; + // ========== 渠道相关字段 ========== + + /** + * 调用渠道的错误码 + */ + private String channelErrorCode; + /** + * 调用渠道的错误提示 + */ + private String channelErrorMsg; + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index ce92080191..1ac5c04af6 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -47,7 +47,7 @@ public class PayTransferCreateReqDTO { * 商户转账单编号 */ @NotEmpty(message = "商户转账单编号能为空") - private String merchantOrderId; + private String merchantTransferId; /** * 转账金额,单位:分 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index cead3232c3..98abf5d3a0 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -31,7 +31,7 @@ public class PayTransferRespDTO { /** * 商户转账单编号 */ - private String merchantOrderId; + private String merchantTransferId; // ========== 转账相关字段 ========== diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java index 595f97d034..ccc538bc9b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/refund/PayRefundApiImpl.java @@ -1,14 +1,14 @@ package cn.iocoder.yudao.module.pay.api.refund; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; -import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; - /** * 退款单 API 实现类 * @@ -23,12 +23,13 @@ public class PayRefundApiImpl implements PayRefundApi { @Override public Long createRefund(PayRefundCreateReqDTO reqDTO) { - return payRefundService.createPayRefund(reqDTO); + return payRefundService.createRefund(reqDTO); } @Override public PayRefundRespDTO getRefund(Long id) { - return PayRefundConvert.INSTANCE.convert02(payRefundService.getRefund(id)); + PayRefundDO refund = payRefundService.getRefund(id); + return BeanUtils.toBean(refund, PayRefundRespDTO.class); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 25f0bf0f7b..f571d882af 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java @@ -66,7 +66,9 @@ public class PayDemoOrderController { @Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 public CommonResult updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { - payDemoOrderService.updateDemoOrderRefunded(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + payDemoOrderService.updateDemoOrderRefunded( + Long.valueOf(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getMerchantRefundId(), notifyReqDTO.getPayRefundId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index 251ec35ce7..033bc95d79 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -55,7 +55,7 @@ public class PayDemoWithdrawController { @Operation(summary = "更新示例提现单的转账状态") // 由 pay-module 转账服务,进行回调 @PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现 public CommonResult updateDemoWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { - demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + demoWithdrawService.updateDemoWithdrawTransferred(Long.valueOf(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java index 3c1a86ec8f..048210169e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.notify; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; @@ -11,7 +12,6 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; -import cn.iocoder.yudao.module.pay.convert.notify.PayNotifyTaskConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; @@ -138,7 +138,12 @@ public class PayNotifyController { // 拼接返回 PayAppDO app = appService.getApp(task.getAppId()); List logs = notifyService.getNotifyLogList(id); - return success(PayNotifyTaskConvert.INSTANCE.convert(task, app, logs)); + return success(BeanUtils.toBean(task, PayNotifyTaskDetailRespVO.class, respVO -> { + if (app != null) { + respVO.setAppName(app.getName()); + } + respVO.setLogs(BeanUtils.toBean(logs, PayNotifyTaskDetailRespVO.Log.class)); + })); } @GetMapping("/page") @@ -150,8 +155,15 @@ public class PayNotifyController { return success(PageResult.empty()); } // 拼接返回 - Map appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId)); - return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap)); + Map apps = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId)); + + // 转换对象 + return success(BeanUtils.toBean(pageResult, PayNotifyTaskRespVO.class, order -> { + PayAppDO app = apps.get(order.getAppId()); + if (app != null) { + order.setAppName(app.getName()); + } + })); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java deleted file mode 100644 index 1e623751ba..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.notify.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 回调通知 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class PayNotifyTaskBaseVO { - - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636") - private Long appId; - - @Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Byte type; - - @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722") - private Long dataId; - - @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Byte status; - - @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26697") - private String merchantOrderId; - - @Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime nextNotifyTime; - - @Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime lastExecuteTime; - - @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED) - private Byte notifyTimes; - - @Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED) - private Byte maxNotifyTimes; - - @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") - private String notifyUrl; - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java index 7c75613e21..739cedf1dc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java @@ -13,19 +13,7 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class PayNotifyTaskDetailRespVO extends PayNotifyTaskBaseVO { - - @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380") - private Long id; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - - @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime updateTime; - - @Schema(description = "应用名称", example = "wx_pay") - private String appName; +public class PayNotifyTaskDetailRespVO extends PayNotifyTaskRespVO { @Schema(description = "回调日志列表") private List logs; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java index 003d2fb336..f6dbc8402d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java @@ -32,6 +32,12 @@ public class PayNotifyTaskPageReqVO extends PageParam { @Schema(description = "商户订单编号", example = "26697") private String merchantOrderId; + @Schema(description = "商户退款编号", example = "26697") + private String merchantRefundId; + + @Schema(description = "商户转账编号", example = "26697") + private String merchantTransferId; + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java index d7f7fe6fb1..75228b1e8c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java @@ -6,17 +6,51 @@ import java.time.LocalDateTime; @Schema(description = "管理后台 - 回调通知 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayNotifyTaskRespVO extends PayNotifyTaskBaseVO { +public class PayNotifyTaskRespVO { @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380") private Long id; - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636") + private Long appId; @Schema(description = "应用名称", example = "wx_pay") private String appName; + @Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Byte type; + + @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722") + private Long dataId; + + @Schema(description = "商户订单编号", example = "26697") + private String merchantOrderId; + + @Schema(description = "商户退款编号", example = "26697") + private String merchantRefundId; + + @Schema(description = "商户转账编号", example = "26697") + private String merchantTransferId; + + @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Byte status; + + @Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime nextNotifyTime; + + @Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime lastExecuteTime; + + @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED) + private Byte notifyTimes; + + @Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED) + private Byte maxNotifyTimes; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime updateTime; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java index bfa7917a0e..c5e84aa700 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java @@ -37,8 +37,7 @@ public class PayWalletRechargeController { return success(true); } - // TODO @jason:发起退款,要 post 操作哈; - @GetMapping("/refund") + @PostMapping("/refund") @Operation(summary = "发起钱包充值退款") @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult refundWalletRecharge(@RequestParam("id") Long id) { @@ -51,7 +50,9 @@ public class PayWalletRechargeController { @PermitAll // 无需登录, 内部校验实现 public CommonResult updateWalletRechargeRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { walletRechargeService.updateWalletRechargeRefunded( - Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId()); + Long.valueOf(notifyReqDTO.getMerchantOrderId()), + Long.valueOf(notifyReqDTO.getMerchantRefundId()), + notifyReqDTO.getPayRefundId()); return success(true); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java deleted file mode 100644 index d0b8e36ff8..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.pay.convert.notify; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO; -import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO; -import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -/** - * 支付通知 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface PayNotifyTaskConvert { - - PayNotifyTaskConvert INSTANCE = Mappers.getMapper(PayNotifyTaskConvert.class); - - PayNotifyTaskRespVO convert(PayNotifyTaskDO bean); - - default PageResult convertPage(PageResult page, Map appMap){ - PageResult result = convertPage(page); - result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName()))); - return result; - } - PageResult convertPage(PageResult page); - - default PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, PayAppDO app, List logs) { - PayNotifyTaskDetailRespVO respVO = convert(task, logs); - if (app != null) { - respVO.setAppName(app.getName()); - } - return respVO; - } - PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, List logs); -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java index 9f087f7029..c94aa00037 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; -import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundDetailsRespVO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExcelVO; import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageItemRespVO; @@ -42,8 +41,6 @@ public interface PayRefundConvert { PayRefundDO convert(PayRefundCreateReqDTO bean); - PayRefundRespDTO convert02(PayRefundDO bean); - default List convertList(List list, Map appMap) { return CollectionUtils.convertList(list, order -> { PayRefundExcelVO excelVO = convertExcel(order); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java index ec2c4a7046..92f1c8c4a2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -60,12 +61,21 @@ public class PayNotifyTaskDO extends TenantBaseDO { * * 1. {@link PayNotifyTypeEnum#ORDER} 时,关联 {@link PayOrderDO#getId()} * 2. {@link PayNotifyTypeEnum#REFUND} 时,关联 {@link PayRefundDO#getId()} + * 3. {@link PayNotifyTypeEnum#TRANSFER} 时,关联 {@link PayTransferDO#getId()} */ private Long dataId; /** * 商户订单编号 */ private String merchantOrderId; + /** + * 商户退款编号 + */ + private String merchantRefundId; + /** + * 商户转账编号 + */ + private String merchantTransferId; /** * 通知状态 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index cadf815609..fe443e96e3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -63,7 +63,7 @@ public class PayTransferDO extends BaseDO { * * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 */ - private String merchantOrderId; + private String merchantTransferId; // ========== 转账相关字段 ========== diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java index cc7701271c..a3e3effa3b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java @@ -37,6 +37,8 @@ public interface PayNotifyTaskMapper extends BaseMapperX { .eqIfPresent(PayNotifyTaskDO::getDataId, reqVO.getDataId()) .eqIfPresent(PayNotifyTaskDO::getStatus, reqVO.getStatus()) .eqIfPresent(PayNotifyTaskDO::getMerchantOrderId, reqVO.getMerchantOrderId()) + .eqIfPresent(PayNotifyTaskDO::getMerchantRefundId, reqVO.getMerchantRefundId()) + .eqIfPresent(PayNotifyTaskDO::getMerchantTransferId, reqVO.getMerchantTransferId()) .betweenIfPresent(PayNotifyTaskDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(PayNotifyTaskDO::getId)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index a3ee56c6e8..05f920900a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -28,7 +28,7 @@ public interface PayTransferMapper extends BaseMapperX { default PayTransferDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { return selectOne(PayTransferDO::getAppId, appId, - PayTransferDO::getMerchantOrderId, merchantOrderId); + PayTransferDO::getMerchantTransferId, merchantOrderId); } default PageResult selectPage(PayTransferPageReqVO reqVO) { @@ -36,7 +36,7 @@ public interface PayTransferMapper extends BaseMapperX { .eqIfPresent(PayTransferDO::getNo, reqVO.getNo()) .eqIfPresent(PayTransferDO::getAppId, reqVO.getAppId()) .eqIfPresent(PayTransferDO::getChannelCode, reqVO.getChannelCode()) - .eqIfPresent(PayTransferDO::getMerchantOrderId, reqVO.getMerchantOrderId()) + .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantOrderId()) .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java index 512007e7dd..18de7b97d4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java @@ -59,8 +59,9 @@ public interface PayDemoOrderService { * 更新示例订单为已退款 * * @param id 编号 + * @param refundId 退款编号 * @param payRefundId 退款订单号 */ - void updateDemoOrderRefunded(Long id, Long payRefundId); + void updateDemoOrderRefunded(Long id, String refundId, Long payRefundId); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java index bf34278e3c..76571f355c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java @@ -184,7 +184,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { // 2.1 生成退款单号 // 一般来说,用户发起退款的时候,都会单独插入一个售后维权表,然后使用该表的 id 作为 refundId - // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id + "-refund" 来演示 + // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id + "-refund" 来演示 String refundId = order.getId() + "-refund"; // 2.2 创建退款单 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() @@ -215,16 +215,18 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { } @Override - public void updateDemoOrderRefunded(Long id, Long payRefundId) { + public void updateDemoOrderRefunded(Long id, String refundId, Long payRefundId) { // 1. 校验并获得退款订单(可退款) - PayRefundRespDTO payRefund = validateDemoOrderCanRefunded(id, payRefundId); + PayRefundRespDTO payRefund = validateDemoOrderCanRefunded(id, refundId, payRefundId); // 2.2 更新退款单到 demo 订单 payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(id) .setRefundTime(payRefund.getSuccessTime())); } - private PayRefundRespDTO validateDemoOrderCanRefunded(Long id, Long payRefundId) { + private PayRefundRespDTO validateDemoOrderCanRefunded(Long id, String refundId, Long payRefundId) { // 1.1 校验示例订单 + // 一般来说,这里应该用 refundId 来查询退款单,然后再校验订单是否匹配 + // 这里我们是个简单的 demo,所以没有售后维权表,直接使用订单 id 来查询订单 PayDemoOrderDO order = payDemoOrderMapper.selectById(id); if (order == null) { throw exception(DEMO_ORDER_NOT_FOUND); @@ -241,7 +243,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { if (payRefund == null) { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_FOUND); } - // 2.2 + // 2.2 必须是退款成功状态 if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_NOT_SUCCESS); } @@ -252,7 +254,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); } // 2.4 校验退款订单匹配(二次) - if (notEqual(payRefund.getMerchantOrderId(), id.toString())) { + if (notEqual(payRefund.getMerchantRefundId(), id.toString() + "-refund")) { log.error("[validateDemoOrderCanRefunded][order({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", id, payRefundId, toJsonString(payRefund)); throw exception(DEMO_ORDER_REFUND_FAIL_REFUND_ORDER_ID_ERROR); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 29e175c2a8..90e79db979 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -75,7 +75,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { // 2.1 创建支付单 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 - .setMerchantOrderId(String.valueOf(withdraw.getId())) // 业务的订单编号 + .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号 .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息 if (ObjectUtil.equal(withdraw.getType(), PayDemoWithdrawTypeEnum.WECHAT.getType())) { @@ -177,7 +177,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_PRICE_NOT_MATCH); } // 2.3 校验转账订单匹配(二次) - if (ObjectUtil.notEqual(payTransfer.getMerchantOrderId(), withdraw.getId().toString())) { + if (ObjectUtil.notEqual(payTransfer.getMerchantTransferId(), withdraw.getId().toString())) { log.error("[validateDemoTransferStatusCanUpdate][withdraw({}) 转账单不匹配({}),请进行处理!payTransfer 数据是:{}]", withdraw.getId(), payTransferId, JsonUtils.toJsonString(payTransfer)); throw exception(DEMO_WITHDRAW_UPDATE_STATUS_FAIL_PAY_MERCHANT_EXISTS); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java index bf56680544..0956087675 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java @@ -31,6 +31,7 @@ import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -97,19 +98,19 @@ public class PayNotifyServiceImpl implements PayNotifyService { PayNotifyTaskDO task = new PayNotifyTaskDO().setType(type).setDataId(dataId); task.setStatus(PayNotifyStatusEnum.WAITING.getStatus()).setNextNotifyTime(LocalDateTime.now()) .setNotifyTimes(0).setMaxNotifyTimes(PayNotifyTaskDO.NOTIFY_FREQUENCY.length + 1); - // 补充 appId + notifyUrl 字段 + // 补充 appId + notifyUrl + merchant* 字段 if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { PayOrderDO order = orderService.getOrder(task.getDataId()); // 不进行非空判断,有问题直接异常 - task.setAppId(order.getAppId()). - setMerchantOrderId(order.getMerchantOrderId()).setNotifyUrl(order.getNotifyUrl()); + task.setAppId(order.getAppId()).setNotifyUrl(order.getNotifyUrl()) + .setMerchantOrderId(order.getMerchantOrderId()); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { - PayRefundDO refundDO = refundService.getRefund(task.getDataId()); - task.setAppId(refundDO.getAppId()) - .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); + PayRefundDO refund = refundService.getRefund(task.getDataId()); + task.setAppId(refund.getAppId()).setNotifyUrl(refund.getNotifyUrl()) + .setMerchantOrderId(refund.getMerchantOrderId()).setMerchantRefundId(refund.getMerchantRefundId()); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { PayTransferDO transfer = transferService.getTransfer(task.getDataId()); - task.setAppId(transfer.getAppId()) - .setMerchantOrderId(transfer.getMerchantOrderId()).setNotifyUrl(transfer.getNotifyUrl()); + task.setAppId(transfer.getAppId()).setNotifyUrl(transfer.getNotifyUrl()) + .setMerchantTransferId(transfer.getMerchantTransferId()); } // 执行插入 @@ -117,10 +118,13 @@ public class PayNotifyServiceImpl implements PayNotifyService { // 必须在事务提交后,在发起任务,否则 PayNotifyTaskDO 还没入库,就提前回调接入的业务 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override public void afterCommit() { - executeNotify(task); + // 异步的原因:避免阻塞当前事务,无需等待结果 + getSelf().executeNotifyAsync(task); } + }); } @@ -166,7 +170,17 @@ public class PayNotifyServiceImpl implements PayNotifyService { } /** - * 同步执行单个支付通知 + * 异步执行单个支付通知 + * + * @param task 通知任务 + */ + @Async + public void executeNotifyAsync(PayNotifyTaskDO task) { + executeNotify(task); + } + + /** + * 【加锁】执行单个支付通知 * * @param task 通知任务 */ @@ -223,9 +237,10 @@ public class PayNotifyServiceImpl implements PayNotifyService { .payOrderId(task.getDataId()).build(); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { request = PayRefundNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) + .merchantRefundId(task.getMerchantRefundId()) .payRefundId(task.getDataId()).build(); } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.TRANSFER.getType())) { - request = PayTransferNotifyReqDTO.builder().merchantOrderId(task.getMerchantOrderId()) + request = PayTransferNotifyReqDTO.builder().merchantTransferId(task.getMerchantTransferId()) .payTransferId(task.getDataId()).build(); } else { throw new RuntimeException("未知的通知任务类型:" + JsonUtils.toJsonString(task)); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java index 258cea9640..bf872eb8e8 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -62,7 +62,7 @@ public interface PayRefundService { * @param reqDTO 退款申请信息 * @return 退款单号 */ - Long createPayRefund(PayRefundCreateReqDTO reqDTO); + Long createRefund(PayRefundCreateReqDTO reqDTO); /** * 渠道的退款通知 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 8df7f88615..57ada01bc2 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -91,7 +91,7 @@ public class PayRefundServiceImpl implements PayRefundService { } @Override - public Long createPayRefund(PayRefundCreateReqDTO reqDTO) { + public Long createRefund(PayRefundCreateReqDTO reqDTO) { // 1.1 校验 App PayAppDO app = appService.validPayApp(reqDTO.getAppKey()); // 1.2 校验支付订单 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 677d5c657c..42f77e6298 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -116,7 +116,7 @@ public class PayTransferServiceImpl implements PayTransferService { } private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO reqDTO, Long appId) { - PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantOrderId()); + PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantOrderId(appId, reqDTO.getMerchantTransferId()); if (transfer != null) { // 只有转账单状态为关闭,才能再次发起转账 if (!PayTransferStatusEnum.isClosed(transfer.getStatus())) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java index f2de1677bd..f2ab50ed68 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; /** * 钱包充值 Service 接口 @@ -16,7 +15,7 @@ public interface PayWalletRechargeService { /** * 创建钱包充值记录(发起充值) * - * @param userId 用户 id + * @param userId 用户编号 * @param userType 用户类型 * @param createReqVO 钱包充值请求 VO * @param userIp 用户Ip @@ -40,8 +39,8 @@ public interface PayWalletRechargeService { /** * 更新钱包充值成功 * - * @param id 钱包充值记录 id - * @param payOrderId 支付订单 id + * @param id 钱包充值记录编号 + * @param payOrderId 支付订单编号 */ void updateWalletRechargerPaid(Long id, Long payOrderId); @@ -56,9 +55,10 @@ public interface PayWalletRechargeService { /** * 更新钱包充值记录为已退款 * - * @param id 钱包充值 id + * @param id 钱包充值记录编号 + * @param refundId 钱包充值退款编号(实际和 id 相同) * @param payRefundId 退款单id */ - void updateWalletRechargeRefunded(Long id, Long payRefundId); + void updateWalletRechargeRefunded(Long id, Long refundId, Long payRefundId); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java index d7144f60e3..9f575d7c27 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java @@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; @@ -21,7 +22,6 @@ import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; -import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO; import jakarta.annotation.Resource; @@ -61,13 +61,15 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { private PayWalletService payWalletService; @Resource private PayOrderService payOrderService; - @Resource - private PayRefundService payRefundService; +// @Resource +// private PayRefundService payRefundService; @Resource private PayWalletRechargePackageService payWalletRechargePackageService; @Resource public SocialClientApi socialClientApi; + @Resource + private PayRefundApi payRefundApi; @Resource private PayProperties payProperties; @@ -186,7 +188,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { // 3. 创建退款单 String walletRechargeId = String.valueOf(id); String refundId = walletRechargeId + "-refund"; - Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO() + Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) .setMerchantOrderId(walletRechargeId) .setMerchantRefundId(refundId) @@ -199,18 +201,20 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @Override @Transactional(rollbackFor = Exception.class) - public void updateWalletRechargeRefunded(Long id, Long payRefundId) { + public void updateWalletRechargeRefunded(Long id, Long refundId, Long payRefundId) { // 1.1 获取钱包充值记录 + // 说明:因为 id 和 refundId 是相同的,所以直接使用 id 查询即可! PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(id); if (walletRecharge == null) { log.error("[updateWalletRechargerPaid][钱包充值记录不存在,钱包充值记录 id({})]", id); throw exception(WALLET_RECHARGE_NOT_FOUND); } // 1.2 校验钱包充值是否可以更新已退款 - PayRefundDO payRefund = validateWalletRechargeCanRefunded(walletRecharge, payRefundId); + PayRefundRespDTO payRefund = validateWalletRechargeCanRefunded(walletRecharge, payRefundId); + // 2. 处理退款结果 PayWalletRechargeDO updateObj = new PayWalletRechargeDO().setId(id); - // 退款成功 + // 情况一:退款成功 if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { // 2.1 更新钱包余额 payWalletService.reduceWalletBalance(walletRecharge.getWalletId(), id, @@ -219,19 +223,19 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { updateObj.setRefundStatus(SUCCESS.getStatus()).setRefundTime(payRefund.getSuccessTime()) .setRefundTotalPrice(walletRecharge.getTotalPrice()).setRefundPayPrice(walletRecharge.getPayPrice()) .setRefundBonusPrice(walletRecharge.getBonusPrice()); - } - // 退款失败 - if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { + // 情况二:退款失败 + } else if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { // 2.2 解冻余额 payWalletService.unfreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); updateObj.setRefundStatus(FAILURE.getStatus()); } + // 3. 更新钱包充值的退款字段 walletRechargeMapper.updateByIdAndRefunded(id, WAITING.getStatus(), updateObj); } - private PayRefundDO validateWalletRechargeCanRefunded(PayWalletRechargeDO walletRecharge, Long payRefundId) { + private PayRefundRespDTO validateWalletRechargeCanRefunded(PayWalletRechargeDO walletRecharge, Long payRefundId) { // 1. 校验退款订单匹配 if (notEqual(walletRecharge.getPayRefundId(), payRefundId)) { log.error("[validateWalletRechargeCanRefunded][钱包充值({}) 退款单不匹配({}),请进行处理!钱包充值的数据是:{}]", @@ -240,7 +244,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { } // 2.1 校验退款订单 - PayRefundDO payRefund = payRefundService.getRefund(payRefundId); + PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); if (payRefund == null) { log.error("[validateWalletRechargeCanRefunded][payRefund({})不存在]", payRefundId); throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_NOT_FOUND); @@ -252,7 +256,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); } // 2.3 校验退款订单商户订单是否匹配 - if (notEqual(payRefund.getMerchantOrderId(), walletRecharge.getId().toString())) { + if (notEqual(payRefund.getMerchantRefundId(), walletRecharge.getId().toString())) { log.error("[validateWalletRechargeCanRefunded][钱包({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", walletRecharge.getId(), payRefundId, toJsonString(payRefund)); throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java index c001336fc3..adbf480d2a 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java @@ -215,7 +215,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(appService.validPayApp(eq("demo"))).thenReturn(app); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), PAY_ORDER_NOT_FOUND); } @@ -241,7 +241,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), PAY_ORDER_REFUND_FAIL_STATUS_ERROR); } @@ -260,7 +260,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(orderService.getOrder(eq(1L), eq("100"))).thenReturn(order); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_PRICE_EXCEED); } @@ -283,7 +283,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { refundMapper.insert(refund); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_PRICE_EXCEED); } @@ -307,7 +307,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(channelService.validPayChannel(eq(1L))).thenReturn(channel); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), CHANNEL_NOT_FOUND); } @@ -339,7 +339,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { refundMapper.insert(refund); // 调用,并断言异常 - assertServiceException(() -> refundService.createPayRefund(reqDTO), + assertServiceException(() -> refundService.createRefund(reqDTO), REFUND_EXISTS); } @@ -369,7 +369,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException()); // 调用 - Long refundId = refundService.createPayRefund(reqDTO); + Long refundId = refundService.createRefund(reqDTO); // 断言 PayRefundDO refundDO = refundMapper.selectById(refundId); assertPojoEquals(reqDTO, refundDO); @@ -422,7 +422,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { }))).thenReturn(refundRespDTO); // 调用 - Long refundId = refundService.createPayRefund(reqDTO); + Long refundId = refundService.createRefund(reqDTO); // 断言 PayRefundDO refundDO = refundMapper.selectById(refundId); assertPojoEquals(reqDTO, refundDO); From 0e7ce637192e5ca96c4ff8abbe0e3feb13dc6672 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 May 2025 17:15:30 +0800 Subject: [PATCH 12/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E8=BD=AC=E8=B4=A6=E5=8D=95=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/pay/enums/DictTypeConstants.java | 2 + .../admin/refund/PayRefundController.java | 8 +-- .../admin/transfer/PayTransferController.java | 51 +++++++++++++-- .../vo/PayTransferPageItemRespVO.java | 62 ------------------- .../transfer/vo/PayTransferPageReqVO.java | 3 + .../admin/transfer/vo/PayTransferRespVO.java | 42 ++++++++++--- .../dal/mysql/transfer/PayTransferMapper.java | 1 + .../pay/service/app/PayAppServiceImpl.java | 5 ++ 8 files changed, 90 insertions(+), 84 deletions(-) delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java index 8f0d9b718d..680ed9ba0d 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java @@ -15,4 +15,6 @@ public interface DictTypeConstants { String NOTIFY_STATUS = "pay_notify_status"; // 回调状态 + String TRANSFER_STATUS = "pay_transfer_status"; // 转账状态 + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java index a476ff9b5d..76fb04588d 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java @@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -78,13 +77,8 @@ public class PayRefundController { @PreAuthorize("@ss.hasPermission('pay:refund:export')") @ApiAccessLog(operateType = EXPORT) public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { + HttpServletResponse response) throws IOException { List list = refundService.getRefundList(exportReqVO); - if (CollectionUtil.isEmpty(list)) { - ExcelUtils.write(response, "退款订单.xls", "数据", - PayRefundExcelVO.class, new ArrayList<>()); - return; - } // 拼接返回 Map appMap = appService.getAppMap(convertList(list, PayRefundDO::getAppId)); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java index add9064974..cfc30b297a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java @@ -1,16 +1,20 @@ package cn.iocoder.yudao.module.pay.controller.admin.transfer; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageItemRespVO; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferRespVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; +import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -19,7 +23,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; +import java.util.Map; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; @Tag(name = "管理后台 - 转账单") @RestController @@ -29,22 +39,53 @@ public class PayTransferController { @Resource private PayTransferService payTransferService; + @Resource + private PayAppService payAppService; @GetMapping("/get") @Operation(summary = "获得转账订单") @PreAuthorize("@ss.hasPermission('pay:transfer:query')") public CommonResult getTransfer(@RequestParam("id") Long id) { PayTransferDO transfer = payTransferService.getTransfer(id); - return success(BeanUtils.toBean(transfer, PayTransferRespVO.class)); + if (transfer == null) { + return success(new PayTransferRespVO()); + } + + // 拼接数据 + PayAppDO app = payAppService.getApp(transfer.getAppId()); + return success(BeanUtils.toBean(transfer, PayTransferRespVO.class, transferVO -> { + if (app != null) { + transferVO.setAppName(app.getName()); + } + })); } - // TODO @芋艿:get 和 page 的返回,是不是统一融合 @GetMapping("/page") @Operation(summary = "获得转账订单分页") @PreAuthorize("@ss.hasPermission('pay:transfer:query')") - public CommonResult> getTransferPage(@Valid PayTransferPageReqVO pageVO) { + public CommonResult> getTransferPage(@Valid PayTransferPageReqVO pageVO) { PageResult pageResult = payTransferService.getTransferPage(pageVO); - return success(BeanUtils.toBean(pageResult, PayTransferPageItemRespVO.class)); + + // 拼接数据 + Map apps = payAppService.getAppMap(convertList(pageResult.getList(), PayTransferDO::getAppId)); + return success(BeanUtils.toBean(pageResult, PayTransferRespVO.class, transferVO -> { + if (apps.containsKey(transferVO.getAppId())) { + transferVO.setAppName(apps.get(transferVO.getAppId()).getName()); + } + })); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出转账订单 Excel") + @PreAuthorize("@ss.hasPermission('pay:transfer:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportTransfer(PayTransferPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PAGE_SIZE_NONE); + PageResult pageResult = getTransferPage(pageReqVO).getData(); + + // 导出 Excel + ExcelUtils.write(response, "转账订单.xls", "数据", PayTransferRespVO.class, pageResult.getList()); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java deleted file mode 100644 index 9a7e46f0c7..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageItemRespVO.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.transfer.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * @author jason - */ -@Schema(description = "管理后台 - 转账单分页项 Response VO") -@Data -public class PayTransferPageItemRespVO { - - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2931") - private Long id; - - @Schema(description = "转账单号", requiredMode = Schema.RequiredMode.REQUIRED) - private String no; - - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12831") - private Long appId; - - @Schema(description = "转账渠道编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24833") - private Long channelId; - - @Schema(description = "转账渠道编码", requiredMode = Schema.RequiredMode.REQUIRED) - private String channelCode; - - @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") - private String merchantOrderId; - - @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer type; - - @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer status; - - @Schema(description = "转账成功时间") - private LocalDateTime successTime; - - @Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "964") - private Integer price; - - @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED) - private String subject; - - @Schema(description = "收款人姓名", example = "王五") - private String userName; - - @Schema(description = "支付宝登录号", example = "29245") - private String alipayLogonId; - - @Schema(description = "微信 openId", example = "26589") - private String openid; - - @Schema(description = "渠道转账单号") - private String channelTransferNo; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java index e00b48f807..08a6d45c59 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferPageReqVO.java @@ -32,6 +32,9 @@ public class PayTransferPageReqVO extends PageParam { @Schema(description = "收款人姓名", example = "王五") private String userName; + @Schema(description = "收款人账号", example = "26589") + private String userAccount; + @Schema(description = "渠道转账单号") private String channelTransferNo; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java index aec3a274bd..9e98db1170 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java @@ -1,5 +1,12 @@ package cn.iocoder.yudao.module.pay.controller.admin.transfer.vo; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert; +import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; @@ -7,53 +14,65 @@ import java.util.Map; @Schema(description = "管理后台 - 转账单 Response VO") @Data +@ExcelIgnoreUnannotated public class PayTransferRespVO { + @ExcelProperty("转账单编号") @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2931") private Long id; + @ExcelProperty("转账单号") @Schema(description = "转账单号", requiredMode = Schema.RequiredMode.REQUIRED) private String no; @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12831") private Long appId; + @ExcelProperty("应用名称") + @Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String appName; + @Schema(description = "转账渠道编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24833") private Long channelId; + @ExcelProperty(value = "转账渠道", converter = DictConvert.class) + @DictFormat(DictTypeConstants.CHANNEL_CODE) @Schema(description = "转账渠道编码", requiredMode = Schema.RequiredMode.REQUIRED) private String channelCode; + @ExcelProperty("商户转账单编号") @Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481") - private String merchantOrderId; - - @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer type; + private String merchantTransferId; + @ExcelProperty(value = "转账状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.TRANSFER_STATUS) @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Integer status; + @ExcelProperty("转账成功时间") @Schema(description = "转账成功时间") private LocalDateTime successTime; @Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "964") + @ExcelProperty(value = "转账金额", converter = MoneyConvert.class) private Integer price; - @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("转账标题") + @Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "冲冲冲!") private String subject; @Schema(description = "收款人姓名", example = "王五") + @ExcelProperty("收款人姓名") private String userName; - @Schema(description = "支付宝登录号", example = "29245") - private String alipayLogonId; - - @Schema(description = "微信 openId", example = "26589") - private String openid; + @Schema(description = "收款人账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26589") + @ExcelProperty("收款人账号") + private String userAccount; @Schema(description = "异步通知商户地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") private String notifyUrl; + @ExcelProperty("用户 IP") @Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED) private String userIp; @@ -61,11 +80,13 @@ public class PayTransferRespVO { private Map channelExtras; @Schema(description = "渠道转账单号") + @ExcelProperty("渠道转账单号") private String channelTransferNo; @Schema(description = "调用渠道的错误码") private String channelErrorCode; + @ExcelProperty("渠道错误提示") @Schema(description = "调用渠道的错误提示") private String channelErrorMsg; @@ -73,6 +94,7 @@ public class PayTransferRespVO { private String channelNotifyData; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index 05f920900a..59e6b3eb53 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java @@ -39,6 +39,7 @@ public interface PayTransferMapper extends BaseMapperX { .eqIfPresent(PayTransferDO::getMerchantTransferId, reqVO.getMerchantOrderId()) .eqIfPresent(PayTransferDO::getStatus, reqVO.getStatus()) .likeIfPresent(PayTransferDO::getUserName, reqVO.getUserName()) + .likeIfPresent(PayTransferDO::getUserAccount, reqVO.getUserAccount()) .eqIfPresent(PayTransferDO::getChannelTransferNo, reqVO.getChannelTransferNo()) .betweenIfPresent(PayTransferDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(PayTransferDO::getId)); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java index c0e7558f11..67fd17b0f4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.pay.service.app; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppCreateReqVO; @@ -17,6 +18,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.util.Collection; +import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -116,6 +118,9 @@ public class PayAppServiceImpl implements PayAppService { @Override public List getAppList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } return appMapper.selectBatchIds(ids); } From b91a30dd3e29fc652a9efaf9db3cd4a380a4ff41 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 10 May 2025 20:05:17 +0800 Subject: [PATCH 13/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E5=A2=9E=E5=8A=A0=20channelPackageInfo=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=AF=B9=E6=8E=A5=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E8=BD=AC=E8=B4=A6=20API=EF=BC=88=E5=A4=AA?= =?UTF-8?q?=E9=9A=BE=E4=BA=86=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81?= =?UTF-8?q?=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81?= =?UTF-8?q?=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81=EF=BC=81?= =?UTF-8?q?=EF=BC=81=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 2 +- .../vo/withdraw/BrokerageWithdrawBaseVO.java | 68 ------------------- .../vo/withdraw/BrokerageWithdrawRespVO.java | 57 +++++++++++++--- .../brokerage/BrokerageWithdrawDO.java | 7 ++ .../BrokerageWithdrawServiceImpl.java | 6 +- .../pay/api/transfer/PayTransferApi.java | 6 +- .../dto/PayTransferCreateRespDTO.java | 28 ++++++++ .../api/transfer/dto/PayTransferRespDTO.java | 8 +++ .../pay/api/transfer/PayTransferApiImpl.java | 3 +- .../dataobject/demo/PayDemoWithdrawDO.java | 7 ++ .../dataobject/transfer/PayTransferDO.java | 8 +++ .../demo/PayDemoTransferServiceImpl.java | 8 ++- .../service/transfer/PayTransferService.java | 3 +- .../transfer/PayTransferServiceImpl.java | 17 +++-- .../dto/transfer/PayTransferRespDTO.java | 11 ++- .../impl/weixin/AbstractWxPayClient.java | 16 +++-- 16 files changed, 157 insertions(+), 98 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateRespDTO.java diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index bf16cd37d4..5530d93d38 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -75,7 +75,7 @@ 1.16.7 1.4.0 1.9.4 - 4.7.4.B + 4.7.5.B diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java deleted file mode 100644 index 46e63b25b2..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java +++ /dev/null @@ -1,68 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import jakarta.validation.constraints.NotNull; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * 佣金提现 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class BrokerageWithdrawBaseVO { - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11436") - @NotNull(message = "用户编号不能为空") - private Long userId; - - @Schema(description = "提现金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "18781") - @NotNull(message = "提现金额不能为空") - private Integer price; - - @Schema(description = "提现手续费", requiredMode = Schema.RequiredMode.REQUIRED, example = "11417") - @NotNull(message = "提现手续费不能为空") - private Integer feePrice; - - @Schema(description = "当前总佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "18576") - @NotNull(message = "当前总佣金不能为空") - private Integer totalPrice; - - @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "提现类型不能为空") - private Integer type; - - @Schema(description = "真实姓名", example = "赵六") - private String userName; - - @Schema(description = "收款账号", example = "88677912132") - private String userAccount; - - @Schema(description = "银行名称", example = "1") - private String bankName; - - @Schema(description = "开户地址", example = "海淀支行") - private String bankAddress; - - @Schema(description = "收款码", example = "https://www.iocoder.cn") - private String qrCodeUrl; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "状态不能为空") - private Integer status; - - @Schema(description = "审核驳回原因", example = "不对") - private String auditReason; - - @Schema(description = "审核时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime auditTime; - - @Schema(description = "备注", example = "随便") - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java index 4096dd9514..a2a7005bfe 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRespVO.java @@ -2,27 +2,68 @@ package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; import java.time.LocalDateTime; @Schema(description = "管理后台 - 佣金提现 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BrokerageWithdrawRespVO extends BrokerageWithdrawBaseVO { +public class BrokerageWithdrawRespVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") private Long id; + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11436") + private Long userId; + + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String userNickname; + + @Schema(description = "提现金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "18781") + private Integer price; + + @Schema(description = "提现手续费", requiredMode = Schema.RequiredMode.REQUIRED, example = "11417") + private Integer feePrice; + + @Schema(description = "当前总佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "18576") + private Integer totalPrice; + + @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer type; + + @Schema(description = "真实姓名", example = "赵六") + private String userName; + + @Schema(description = "收款账号", example = "88677912132") + private String userAccount; + + @Schema(description = "银行名称", example = "1") + private String bankName; + + @Schema(description = "开户地址", example = "海淀支行") + private String bankAddress; + + @Schema(description = "收款码", example = "https://www.iocoder.cn") + private String qrCodeUrl; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer status; + + @Schema(description = "审核驳回原因", example = "不对") + private String auditReason; + + @Schema(description = "审核时间") + private LocalDateTime auditTime; + + @Schema(description = "备注", example = "随便") + private String remark; + + @Schema(description = "转账单编号", example = "1024") + private Long payTransferId; + @Schema(description = "转账错误提示", example = "余额不足") private String transferErrorMsg; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - private String userNickname; - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java index 0b996eadb4..525a38912e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java @@ -126,5 +126,12 @@ public class BrokerageWithdrawDO extends BaseDO { * 转账错误提示 */ private String transferErrorMsg; + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String transferChannelPackageInfo; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 353f75742b..4546bdce09 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletRespDTO; @@ -152,11 +153,12 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) .setChannelExtras(channelExtras); // 1.3 发起请求 - Long payTransferId = payTransferApi.createTransfer(transferReqDTO); + PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO); // 2. 更新提现记录 brokerageWithdrawMapper.updateById(new BrokerageWithdrawDO().setId(withdraw.getId()) - .setPayTransferId(payTransferId).setTransferChannelCode(channelCode)); + .setPayTransferId(transferRespDTO.getId()).setTransferChannelCode(channelCode) + .setTransferChannelPackageInfo(transferRespDTO.getChannelPackageInfo())); } private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) { diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java index e9312e1862..e3227ebe09 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; - +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import jakarta.validation.Valid; @@ -16,9 +16,9 @@ public interface PayTransferApi { * 创建转账单 * * @param reqDTO 创建请求 - * @return 转账单编号 + * @return 创建结果 */ - Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + PayTransferCreateRespDTO createTransfer(@Valid PayTransferCreateReqDTO reqDTO); /** * 获得转账单 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateRespDTO.java new file mode 100644 index 0000000000..a445eb07f7 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateRespDTO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.pay.api.transfer.dto; + +import lombok.Data; + +/** + * 转账单创建 Response DTO + * + * @author 芋道源码 + */ +@Data +public class PayTransferCreateRespDTO { + + /** + * 编号 + */ + private Long id; + + // ========== 其它字段 ========== + + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String channelPackageInfo; + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index 98abf5d3a0..4db60a64af 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -63,4 +63,12 @@ public class PayTransferRespDTO { */ private String channelErrorMsg; + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String channelPackageInfo; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java index 4109211254..0e759ff280 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; @@ -22,7 +23,7 @@ public class PayTransferApiImpl implements PayTransferApi { private PayTransferService payTransferService; @Override - public Long createTransfer(PayTransferCreateReqDTO reqDTO) { + public PayTransferCreateRespDTO createTransfer(PayTransferCreateReqDTO reqDTO) { return payTransferService.createTransfer(reqDTO); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java index 71d803c02f..c1a9e4bccc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java @@ -80,5 +80,12 @@ public class PayDemoWithdrawDO extends BaseDO { * 转账错误提示 */ private String transferErrorMsg; + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String transferChannelPackageInfo; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index fe443e96e3..69dc506bac 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -135,4 +135,12 @@ public class PayTransferDO extends BaseDO { */ private String channelNotifyData; + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String channelPackageInfo; + } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 90e79db979..0a89e14adf 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.withdraw.PayDemoWithdrawCreateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoWithdrawDO; @@ -83,12 +84,13 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { transferReqDTO.setChannelExtras(PayTransferCreateReqDTO.buildWeiXinChannelExtra1000( "测试活动", "测试奖励")); } - Long payTransferId = payTransferApi.createTransfer(transferReqDTO); + PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO); // 2.2 更新转账单到 demo 示例提现单,并将状态更新为转账中 demoTransferMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), - new PayDemoWithdrawDO().setPayTransferId(payTransferId)); - return payTransferId; + new PayDemoWithdrawDO().setPayTransferId(transferRespDTO.getId()) + .setTransferChannelPackageInfo(transferRespDTO.getChannelPackageInfo())); + return transferRespDTO.getId(); } private PayDemoWithdrawDO validateDemoWithdrawCanTransfer(Long id) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index 6692c2ef25..b62670f496 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.transfer; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import jakarta.validation.Valid; @@ -20,7 +21,7 @@ public interface PayTransferService { * @param reqDTO 创建请求 * @return 转账单编号 */ - Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + PayTransferCreateRespDTO createTransfer(@Valid PayTransferCreateReqDTO reqDTO); /** * 获取转账单 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 42f77e6298..6f1a04dc2b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifie import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; @@ -62,7 +63,7 @@ public class PayTransferServiceImpl implements PayTransferService { private PayNoRedisDAO noRedisDAO; @Override - public Long createTransfer(PayTransferCreateReqDTO reqDTO) { + public PayTransferCreateRespDTO createTransfer(PayTransferCreateReqDTO reqDTO) { // 1.1 校验 App PayAppDO payApp = appService.validPayApp(reqDTO.getAppKey()); // 1.2 校验支付渠道是否有效 @@ -88,12 +89,13 @@ public class PayTransferServiceImpl implements PayTransferService { transferMapper.updateByIdAndStatus(transfer.getId(), transfer.getStatus(), new PayTransferDO().setStatus(PayTransferStatusEnum.WAITING.getStatus())); } + PayTransferRespDTO unifiedTransferResp = null; try { // 3. 调用三方渠道发起转账 PayTransferUnifiedReqDTO transferUnifiedReq = BeanUtils.toBean(reqDTO, PayTransferUnifiedReqDTO.class) .setOutTransferNo(transfer.getNo()) .setNotifyUrl(genChannelTransferNotifyUrl(channel)); - PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); + unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); // 4. 通知转账结果 getSelf().notifyTransfer(channel, unifiedTransferResp); } catch (Throwable e) { @@ -102,7 +104,8 @@ public class PayTransferServiceImpl implements PayTransferService { // 或者,使用相同 no 再次发起转账请求 log.error("[createTransfer][转账编号({}) requestDTO({}) 发生异常]", transfer.getId(), reqDTO, e); } - return transfer.getId(); + return new PayTransferCreateRespDTO().setId(transfer.getId()) + .setChannelPackageInfo(unifiedTransferResp != null ? unifiedTransferResp.getChannelPackageInfo() : null); } /** @@ -154,7 +157,7 @@ public class PayTransferServiceImpl implements PayTransferService { } private void notifyTransferProgressing(PayChannelDO channel, PayTransferRespDTO notify) { - // 1.校验 + // 1. 校验 PayTransferDO transfer = transferMapper.selectByAppIdAndNo(channel.getAppId(), notify.getOutTransferNo()); if (transfer == null) { throw exception(PAY_TRANSFER_NOT_FOUND); @@ -170,7 +173,8 @@ public class PayTransferServiceImpl implements PayTransferService { // 2. 更新状态 int updateCounts = transferMapper.updateByIdAndStatus(transfer.getId(), PayTransferStatusEnum.WAITING.getStatus(), - new PayTransferDO().setStatus(PayTransferStatusEnum.PROCESSING.getStatus())); + new PayTransferDO().setStatus(PayTransferStatusEnum.PROCESSING.getStatus()) + .setChannelPackageInfo(transfer.getChannelPackageInfo())); if (updateCounts == 0) { throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_IS_NOT_WAITING); } @@ -261,6 +265,9 @@ public class PayTransferServiceImpl implements PayTransferService { } int count = 0; for (PayTransferDO transfer : list) { + if (!transfer.getId().equals(54L)) { + continue; + } count += syncTransfer(transfer) ? 1 : 0; } return count; diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java index 2be8b572bc..4a472730b9 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java @@ -22,7 +22,6 @@ public class PayTransferRespDTO { /** * 外部转账单号 - * */ private String outTransferNo; @@ -50,11 +49,19 @@ public class PayTransferRespDTO { */ private String channelErrorMsg; + /** + * 渠道 package 信息 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String channelPackageInfo; + /** * 创建【WAITING】状态的转账返回 */ public static PayTransferRespDTO waitingOf(String channelTransferNo, - String outTransferNo, Object rawData) { + String outTransferNo, Object rawData) { PayTransferRespDTO respDTO = new PayTransferRespDTO(); respDTO.status = PayTransferStatusRespEnum.WAITING.getStatus(); respDTO.channelTransferNo = channelTransferNo; diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 3f5ff93188..643d708728 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -482,11 +482,19 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Sun, 11 May 2025 08:12:42 +0800 Subject: [PATCH 14/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90MALL=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E5=95=86=E5=9F=8E=E5=88=86=E4=BD=A3=E6=8F=90?= =?UTF-8?q?=E7=8E=B0=EF=BC=8C=E5=88=9D=E6=AD=A5=E5=AF=B9=E6=8E=A5=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/trade/enums/DictTypeConstants.java | 3 + .../BrokerageWithdrawStatusEnum.java | 1 - .../AppBrokerageRecordController.java | 9 +- .../AppBrokerageWithdrawController.java | 44 +++++- .../record/AppBrokerageRecordPageReqVO.java | 4 +- .../vo/record/AppBrokerageRecordRespVO.java | 3 + .../AppBrokerageWithdrawCreateReqVO.java | 8 ++ .../AppBrokerageWithdrawPageReqVO.java | 18 +-- .../withdraw/AppBrokerageWithdrawRespVO.java | 17 +++ .../brokerage/BrokerageRecordConvert.java | 6 - .../brokerage/BrokerageWithdrawConvert.java | 19 --- .../brokerage/BrokerageWithdrawDO.java | 7 - .../BrokerageWithdrawServiceImpl.java | 8 +- .../api/transfer/dto/PayTransferRespDTO.java | 7 + .../pay/api/transfer/PayTransferApiImpl.java | 15 +- .../dataobject/demo/PayDemoWithdrawDO.java | 7 - .../demo/PayDemoTransferServiceImpl.java | 3 +- .../transfer/PayTransferServiceImpl.java | 2 +- .../framework/pay/core/client/PayClient.java | 9 +- .../WxPayTransferPartnerNotifyV3Result.java | 129 ------------------ .../core/client/impl/AbstractPayClient.java | 7 +- .../impl/weixin/AbstractWxPayClient.java | 61 +++++---- 22 files changed, 162 insertions(+), 225 deletions(-) delete mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java index ff09e59d89..afde53e838 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java @@ -7,6 +7,9 @@ package cn.iocoder.yudao.module.trade.enums; */ public interface DictTypeConstants { + String BROKERAGE_RECORD_STATUS = "brokerage_record_status"; // 佣金记录状态 + + String BROKERAGE_WITHDRAW_TYPE = "brokerage_withdraw_type"; // 佣金提现类型 String BROKERAGE_WITHDRAW_STATUS = "brokerage_withdraw_status"; // 佣金提现状态 } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawStatusEnum.java index fe574f73e5..c2aab0eea1 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawStatusEnum.java @@ -6,7 +6,6 @@ import lombok.Getter; import java.util.Arrays; -// TODO 芋艿:提现的打通,在纠结下; /** * 佣金提现状态枚举 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java index 709235c182..75e0879773 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java @@ -3,11 +3,13 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; -import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; +import cn.iocoder.yudao.module.trade.enums.DictTypeConstants; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -36,8 +38,9 @@ public class AppBrokerageRecordController { @Operation(summary = "获得分销记录分页") public CommonResult> getBrokerageRecordPage(@Valid AppBrokerageRecordPageReqVO pageReqVO) { PageResult pageResult = brokerageRecordService.getBrokerageRecordPage( - BrokerageRecordConvert.INSTANCE.convert(pageReqVO, getLoginUserId())); - return success(BeanUtils.toBean(pageResult, AppBrokerageRecordRespVO.class)); + BeanUtils.toBean(pageReqVO, BrokerageRecordPageReqVO.class).setUserId(getLoginUserId())); + return success(BeanUtils.toBean(pageResult, AppBrokerageRecordRespVO.class, recordVO -> + recordVO.setStatusName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BROKERAGE_RECORD_STATUS, recordVO.getStatus())))); } @GetMapping("/get-product-brokerage-price") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java index 0847801557..0a1af6f91d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java @@ -1,14 +1,23 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; +import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO; -import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; +import cn.iocoder.yudao.module.trade.enums.DictTypeConstants; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; @@ -16,6 +25,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Objects; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; @@ -29,12 +40,39 @@ public class AppBrokerageWithdrawController { @Resource private BrokerageWithdrawService brokerageWithdrawService; + @Resource + private PayTransferApi payTransferApi; + @GetMapping("/page") @Operation(summary = "获得分销提现分页") public CommonResult> getBrokerageWithdrawPage(AppBrokerageWithdrawPageReqVO pageReqVO) { PageResult pageResult = brokerageWithdrawService.getBrokerageWithdrawPage( - BrokerageWithdrawConvert.INSTANCE.convert(pageReqVO, getLoginUserId())); - return success(BrokerageWithdrawConvert.INSTANCE.convertPage03(pageResult)); + BeanUtils.toBean(pageReqVO, BrokerageWithdrawPageReqVO.class).setUserId(getLoginUserId())); + return success(BeanUtils.toBean(pageResult, AppBrokerageWithdrawRespVO.class, withdrawVO -> + withdrawVO.setTypeName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BROKERAGE_WITHDRAW_TYPE, withdrawVO.getType())) + .setStatusName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BROKERAGE_WITHDRAW_STATUS, withdrawVO.getStatus())))); + } + + @GetMapping("/get") + @Operation(summary = "获得佣金提现") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getBrokerageWithdraw(@RequestParam("id") Long id) { + BrokerageWithdrawDO withdraw = brokerageWithdrawService.getBrokerageWithdraw(id); + if (withdraw == null || ObjUtil.notEqual(withdraw.getUserId(), getLoginUserId())) { + return success(null); + } + // 审核中(转账中),并且是微信转账,需要返回 mchId 用于确认收款 + AppBrokerageWithdrawRespVO withdrawVO = BeanUtils.toBean(withdraw, AppBrokerageWithdrawRespVO.class); + if (Objects.equals(withdraw.getStatus(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()) + && Objects.equals(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType()) + && withdraw.getPayTransferId() != null) { + PayTransferRespDTO transfer = payTransferApi.getTransfer(withdraw.getPayTransferId()); + if (transfer != null) { + withdrawVO.setTransferChannelPackageInfo(transfer.getChannelPackageInfo()) + .setTransferChannelMchId(transfer.getChannelMchId()); + } + } + return success(withdrawVO); } @PostMapping("/create") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java index 2100c2324d..9ac4dbde6b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java @@ -20,11 +20,11 @@ public class AppBrokerageRecordPageReqVO extends PageParam { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "业务类型", example = "1") @InEnum(value = BrokerageRecordBizTypeEnum.class, message = "业务类型必须是 {value}") private Integer bizType; - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "状态", example = "1") @InEnum(value = BrokerageRecordStatusEnum.class, message = "状态必须是 {value}") private Integer status; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordRespVO.java index 993006e34a..7e671efe7a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordRespVO.java @@ -24,6 +24,9 @@ public class AppBrokerageRecordRespVO { @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer status; + @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "待结算") + private String statusName; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java index 377731b6dc..180b016a39 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java @@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; import lombok.Data; import org.hibernate.validator.constraints.URL; @@ -22,6 +24,7 @@ public class AppBrokerageWithdrawCreateReqVO { @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") @PositiveOrZero(message = "提现金额不能小于 0") + @Min(value = 30, message = "微信提现金额不能小于 0.3", groups = {WechatApi.class}) @NotNull(message = "提现金额不能为空") private Integer price; @@ -43,6 +46,11 @@ public class AppBrokerageWithdrawCreateReqVO { @Schema(description = "开户地址", example = "海淀支行") private String bankAddress; + @Schema(description = "转账渠道", example = "wx_lite") + @NotNull(message = "转账渠道不能为空", groups = {WechatApi.class}) + @InEnum(PayChannelEnum.class) + private String transferChannelCode; + public interface Wallet { } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawPageReqVO.java index b1757d43ef..9b319690fc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawPageReqVO.java @@ -1,22 +1,22 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "应用 App - 分销提现分页 Request VO") @Data public class AppBrokerageWithdrawPageReqVO extends PageParam { - @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "类型必须是 {value}") - private Integer type; + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @InEnum(value = BrokerageWithdrawStatusEnum.class, message = "状态必须是 {value}") - private Integer status; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawRespVO.java index 4cfe930c8a..3d0b988ff2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawRespVO.java @@ -12,6 +12,12 @@ public class AppBrokerageWithdrawRespVO { @Schema(description = "提现编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Long id; + @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer type; + + @Schema(description = "提现类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "微信") + private String typeName; + @Schema(description = "提现状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Integer status; @@ -24,4 +30,15 @@ public class AppBrokerageWithdrawRespVO { @Schema(description = "提现时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; + // ========== 微信转账专属 ========== + + @Schema(description = "转账单编号", example = "1024") + private Long payTransferId; + + @Schema(description = "渠道 package 信息") + private String transferChannelPackageInfo; + + @Schema(description = "渠道商户号") + private String transferChannelMchId; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java index 0f1fe61781..ff66e00122 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java @@ -1,15 +1,11 @@ package cn.iocoder.yudao.module.trade.convert.brokerage; -import cn.hutool.core.math.Money; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordRespVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; @@ -68,8 +64,6 @@ public interface BrokerageRecordConvert { return result; } - BrokerageRecordPageReqVO convert(AppBrokerageRecordPageReqVO pageReqVO, Long userId); - default PageResult convertPage03(PageResult pageResult, Map userMap) { for (AppBrokerageUserRankByPriceRespVO vo : pageResult.getList()) { copyTo(userMap.get(vo.getId()), vo); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageWithdrawConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageWithdrawConvert.java index 4b818af253..aa4df9627c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageWithdrawConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageWithdrawConvert.java @@ -1,15 +1,9 @@ package cn.iocoder.yudao.module.trade.convert.brokerage; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; -import cn.iocoder.yudao.module.trade.enums.DictTypeConstants; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -27,8 +21,6 @@ public interface BrokerageWithdrawConvert { BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class); - BrokerageWithdrawDO convert(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId, Integer feePrice); - BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean); List convertList(List list); @@ -43,15 +35,4 @@ public interface BrokerageWithdrawConvert { return result; } - PageResult convertPage02(PageResult pageResult); - - default PageResult convertPage03(PageResult pageResult) { - PageResult result = convertPage02(pageResult); - for (AppBrokerageWithdrawRespVO vo : result.getList()) { - vo.setStatusName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BROKERAGE_WITHDRAW_STATUS, vo.getStatus())); - } - return result; - } - - BrokerageWithdrawPageReqVO convert(AppBrokerageWithdrawPageReqVO pageReqVO, Long userId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java index 525a38912e..0b996eadb4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java @@ -126,12 +126,5 @@ public class BrokerageWithdrawDO extends BaseDO { * 转账错误提示 */ private String transferErrorMsg; - /** - * 渠道 package 信息 - * - * 特殊:目前只有微信转账有这个东西!!! - * @see JSAPI 调起用户确认收款 - */ - private String transferChannelPackageInfo; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 4546bdce09..ff258bb698 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; @@ -18,7 +19,6 @@ import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; -import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper; @@ -157,8 +157,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 2. 更新提现记录 brokerageWithdrawMapper.updateById(new BrokerageWithdrawDO().setId(withdraw.getId()) - .setPayTransferId(transferRespDTO.getId()).setTransferChannelCode(channelCode) - .setTransferChannelPackageInfo(transferRespDTO.getChannelPackageInfo())); + .setPayTransferId(transferRespDTO.getId()).setTransferChannelCode(channelCode)); } private BrokerageWithdrawDO validateBrokerageWithdrawExists(Long id) { @@ -190,7 +189,8 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { // 2.1 计算手续费 Integer feePrice = calculateFeePrice(createReqVO.getPrice(), tradeConfig.getBrokerageWithdrawFeePercent()); // 2.2 创建佣金提现记录 - BrokerageWithdrawDO withdraw = BrokerageWithdrawConvert.INSTANCE.convert(createReqVO, userId, feePrice); + BrokerageWithdrawDO withdraw = BeanUtils.toBean(createReqVO, BrokerageWithdrawDO.class) + .setUserId(userId).setFeePrice(feePrice); brokerageWithdrawMapper.insert(withdraw); // 3. 创建用户佣金记录 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java index 4db60a64af..52126ce772 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -70,5 +70,12 @@ public class PayTransferRespDTO { * @see JSAPI 调起用户确认收款 */ private String channelPackageInfo; + /** + * 渠道商户号 + * + * 特殊:目前只有微信转账有这个东西!!! + * @see JSAPI 调起用户确认收款 + */ + private String channelMchId; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java index 0e759ff280..87634681d1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateRespDTO; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; +import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -21,6 +24,8 @@ public class PayTransferApiImpl implements PayTransferApi { @Resource private PayTransferService payTransferService; + @Resource + private PayChannelService payChannelService; @Override public PayTransferCreateRespDTO createTransfer(PayTransferCreateReqDTO reqDTO) { @@ -30,7 +35,15 @@ public class PayTransferApiImpl implements PayTransferApi { @Override public PayTransferRespDTO getTransfer(Long id) { PayTransferDO transfer = payTransferService.getTransfer(id); - return BeanUtils.toBean(transfer, PayTransferRespDTO.class); + if (transfer == null) { + return null; + } + PayChannelDO channel = payChannelService.getChannel(transfer.getChannelId()); + String mchId = null; + if (channel != null && channel.getConfig() instanceof WxPayClientConfig) { + mchId = ((WxPayClientConfig) channel.getConfig()).getMchId(); + } + return BeanUtils.toBean(transfer, PayTransferRespDTO.class).setChannelMchId(mchId); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java index c1a9e4bccc..71d803c02f 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoWithdrawDO.java @@ -80,12 +80,5 @@ public class PayDemoWithdrawDO extends BaseDO { * 转账错误提示 */ private String transferErrorMsg; - /** - * 渠道 package 信息 - * - * 特殊:目前只有微信转账有这个东西!!! - * @see JSAPI 调起用户确认收款 - */ - private String transferChannelPackageInfo; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 0a89e14adf..de08f8ecb5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java @@ -88,8 +88,7 @@ public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { // 2.2 更新转账单到 demo 示例提现单,并将状态更新为转账中 demoTransferMapper.updateByIdAndStatus(withdraw.getId(), withdraw.getStatus(), - new PayDemoWithdrawDO().setPayTransferId(transferRespDTO.getId()) - .setTransferChannelPackageInfo(transferRespDTO.getChannelPackageInfo())); + new PayDemoWithdrawDO().setPayTransferId(transferRespDTO.getId())); return transferRespDTO.getId(); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 6f1a04dc2b..b3fd122e13 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -174,7 +174,7 @@ public class PayTransferServiceImpl implements PayTransferService { int updateCounts = transferMapper.updateByIdAndStatus(transfer.getId(), PayTransferStatusEnum.WAITING.getStatus(), new PayTransferDO().setStatus(PayTransferStatusEnum.PROCESSING.getStatus()) - .setChannelPackageInfo(transfer.getChannelPackageInfo())); + .setChannelPackageInfo(notify.getChannelPackageInfo())); if (updateCounts == 0) { throw exception(PAY_TRANSFER_NOTIFY_FAIL_STATUS_IS_NOT_WAITING); } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java index a7abb20e09..b5031b2a28 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java @@ -14,7 +14,7 @@ import java.util.Map; * * @author 芋道源码 */ -public interface PayClient { +public interface PayClient { /** * 获得渠道编号 @@ -23,6 +23,13 @@ public interface PayClient { */ Long getId(); + /** + * 获得渠道配置 + * + * @return 渠道配置 + */ + Config getConfig(); + // ============ 支付相关 ========== /** diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java deleted file mode 100644 index a25cc15696..0000000000 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/WxPayTransferPartnerNotifyV3Result.java +++ /dev/null @@ -1,129 +0,0 @@ -package cn.iocoder.yudao.framework.pay.core.client.dto.transfer; - -import com.github.binarywang.wxpay.bean.notify.OriginNotifyResponse; -import com.github.binarywang.wxpay.bean.notify.WxPayBaseNotifyV3Result; -import com.google.gson.annotations.SerializedName; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; - -// TODO @luchi:这个可以复用 wxjava 里的类么? -@NoArgsConstructor -public class WxPayTransferPartnerNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result { - - private static final long serialVersionUID = -1L; - - /** - * 源数据 - */ - private OriginNotifyResponse rawData; - - /** - * 解密后的数据 - */ - private TransferNotifyResult result; - - @Override - public void setRawData(OriginNotifyResponse rawData) { - this.rawData = rawData; - } - - @Override - public void setResult(TransferNotifyResult data) { - this.result = data; - } - - public TransferNotifyResult getResult() { - return result; - } - - public OriginNotifyResponse getRawData() { - return rawData; - } - - @Data - @NoArgsConstructor - public static class TransferNotifyResult implements Serializable { - private static final long serialVersionUID = 1L; - - /*********************** 公共字段 ******************** - - /** - * 商家批次单号 - */ - @SerializedName(value = "out_batch_no") - protected String outBatchNo; - - /** - * 微信批次单号 - */ - @SerializedName(value = "batch_id") - protected String batchId; - - /** - * 批次状态 - */ - @SerializedName(value = "batch_status") - protected String batchStatus; - - /** - * 批次总笔数 - */ - @SerializedName(value = "total_num") - protected Integer totalNum; - - /** - * 批次总金额 - */ - @SerializedName(value = "total_amount") - protected Integer totalAmount; - - /** - * 批次更新时间 - */ - @SerializedName(value = "update_time") - private String updateTime; - - /*********************** FINISHED ******************** - - /** - * 转账成功金额 - */ - @SerializedName(value = "success_amount") - protected Integer successAmount; - - /** - * 转账成功笔数 - */ - @SerializedName(value = "success_num") - protected Integer successNum; - - /** - * 转账失败金额 - */ - @SerializedName(value = "fail_amount") - protected Integer failAmount; - - /** - * 转账失败笔数 - */ - @SerializedName(value = "fail_num") - protected Integer failNum; - - /*********************** CLOSED ******************** - - /** - * 商户号 - */ - @SerializedName(value = "mchid") - protected String mchId; - - /** - * 批次关闭原因 - */ - @SerializedName(value = "close_reason") - protected String closeReason; - - } -} diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index ad4f9ad024..3ea225b7b1 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString * @author 芋道源码 */ @Slf4j -public abstract class AbstractPayClient implements PayClient { +public abstract class AbstractPayClient implements PayClient { /** * 渠道编号 @@ -74,6 +74,11 @@ public abstract class AbstractPayClient implemen return channelId; } + @Override + public Config getConfig() { + return config; + } + // ============ 支付相关 ========== @Override diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index 643d708728..a9a93a96ba 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -15,13 +15,13 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.WxPayTransferPartnerNotifyV3Result; import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import com.github.binarywang.wxpay.bean.notify.*; import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult; +import com.github.binarywang.wxpay.bean.transfer.TransferBillsNotifyResult; import com.github.binarywang.wxpay.bean.transfer.TransferBillsRequest; import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult; import com.github.binarywang.wxpay.config.WxPayConfig; @@ -354,34 +354,6 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body, Map headers) throws WxPayException { - switch (config.getApiVersion()) { - case API_VERSION_V3: - return parseTransferNotifyV3(body, headers); - case API_VERSION_V2: - throw new UnsupportedOperationException("V2 版本暂不支持,建议使用 V3 版本"); - default: - throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); - } - } - - private PayTransferRespDTO parseTransferNotifyV3(String body, Map headers) throws WxPayException { - // 1. 解析回调 - SignatureHeader signatureHeader = getRequestHeader(headers); - // TODO @luchi:这个可以复用 wxjava 里的类么? - WxPayTransferPartnerNotifyV3Result response = client.baseParseOrderNotifyV3Result(body, signatureHeader, WxPayTransferPartnerNotifyV3Result.class, WxPayTransferPartnerNotifyV3Result.TransferNotifyResult.class); - WxPayTransferPartnerNotifyV3Result.TransferNotifyResult result = response.getResult(); - // 2. 构建结果 - if (Objects.equals("FINISHED", result.getBatchStatus())) { - if (result.getFailNum() <= 0) { - return PayTransferRespDTO.successOf(result.getBatchId(), parseDateV3(result.getUpdateTime()), - result.getOutBatchNo(), response); - } - } - return PayTransferRespDTO.closedOf(result.getBatchStatus(), result.getCloseReason(), result.getOutBatchNo(), response); - } - @Override protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException { try { @@ -522,6 +494,37 @@ public abstract class AbstractWxPayClient extends AbstractPayClient params, String body, Map headers) throws WxPayException { + switch (config.getApiVersion()) { + case API_VERSION_V3: + return parseTransferNotifyV3(body, headers); + case API_VERSION_V2: + throw new UnsupportedOperationException("V2 版本暂不支持,建议使用 V3 版本"); + default: + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } + + private PayTransferRespDTO parseTransferNotifyV3(String body, Map headers) throws WxPayException { + // 1. 解析回调 + SignatureHeader signatureHeader = getRequestHeader(headers); + TransferBillsNotifyResult response = client.getTransferService().parseTransferBillsNotifyResult(body, signatureHeader); + TransferBillsNotifyResult.DecryptNotifyResult result = response.getResult(); + + // 2. 创建返回结果 + String state = result.getState(); + if (ObjectUtils.equalsAny(state, "ACCEPTED", "PROCESSING", "WAIT_USER_CONFIRM", "TRANSFERING")) { + return PayTransferRespDTO.processingOf(result.getTransferBillNo(), result.getOutBillNo(), response); + } + if (Objects.equals("SUCCESS", state)) { + return PayTransferRespDTO.successOf(result.getTransferBillNo(), parseDateV3(result.getUpdateTime()), + result.getOutBillNo(), response); + } + return PayTransferRespDTO.closedOf(state, result.getFailReason(), + result.getOutBillNo(), response); + } + // ========== 各种工具方法 ========== /** From fd8567f0fae85cffc1aa8bc56900b8623531c9c3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 May 2025 08:52:52 +0800 Subject: [PATCH 15/19] =?UTF-8?q?fix=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91wxjava=20v3=20=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=EF=BC=8Cconnection=20pool=20shutdown=20=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/weixin/AbstractWxPayClient.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index a9a93a96ba..0bf9614cdc 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -69,6 +69,8 @@ public abstract class AbstractWxPayClient extends AbstractPayClient headers) throws WxPayException { // 1. 解析回调 -// SignatureHeader signatureHeader = getRequestHeader(headers); - SignatureHeader signatureHeader = null; + SignatureHeader signatureHeader = getRequestHeader(headers); WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, signatureHeader); WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult(); // 2. 构建结果 @@ -223,6 +226,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient Date: Sun, 11 May 2025 12:39:05 +0800 Subject: [PATCH 16/19] =?UTF-8?q?feat=EF=BC=9A=E3=80=90MALL=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E5=95=86=E5=9F=8E=E5=88=86=E4=BD=A3=E6=8F=90?= =?UTF-8?q?=E7=8E=B0=EF=BC=8C=E5=AE=8C=E6=88=90=E5=AF=B9=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E8=BD=AC=E8=B4=A6=EF=BC=88=E5=B0=8F=E7=A8=8B=E5=BA=8F=EF=BC=89?= =?UTF-8?q?=E7=9A=84=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppBrokerageRecordController.java | 3 +- .../transfer/AppPayTransferController.java | 36 +++++++++++++++++++ .../service/order/PayOrderServiceImpl.java | 4 +-- .../service/refund/PayRefundServiceImpl.java | 2 +- .../service/transfer/PayTransferService.java | 7 ++++ .../transfer/PayTransferServiceImpl.java | 13 +++++-- .../channel/PayChannelServiceTest.java | 2 +- .../service/order/PayOrderServiceTest.java | 22 ++++++------ .../service/refund/PayRefundServiceTest.java | 10 +++--- .../PayClientFactoryImplIntegrationTest.java | 8 ++--- 10 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/transfer/AppPayTransferController.java diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java index 75e0879773..20e13b1502 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java @@ -31,6 +31,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi @Validated @Slf4j public class AppBrokerageRecordController { + @Resource private BrokerageRecordService brokerageRecordService; @@ -49,4 +50,4 @@ public class AppBrokerageRecordController { return success(brokerageRecordService.calculateProductBrokeragePrice(getLoginUserId(), spuId)); } -} +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/transfer/AppPayTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/transfer/AppPayTransferController.java new file mode 100644 index 0000000000..bf8fc29ab0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/transfer/AppPayTransferController.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.pay.controller.app.transfer; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 转账单") +@RestController +@RequestMapping("/pay/transfer") +@Validated +@Slf4j +public class AppPayTransferController { + + @Resource + private PayTransferService transferService; + + @GetMapping("/sync") + @Operation(summary = "同步转账单") // 目的:解决微信转账的异步回调可能有延迟的问题 + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult syncTransfer(@RequestParam("id") Long id) { + transferService.syncTransfer(id); + return success(true); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java index 414031f854..5ed2ec74c4 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -140,7 +140,7 @@ public class PayOrderServiceImpl implements PayOrderService { PayOrderDO order = validateOrderCanSubmit(reqVO.getId()); // 1.32 校验支付渠道是否有效 PayChannelDO channel = validateChannelCanSubmit(order.getAppId(), reqVO.getChannelCode()); - PayClient client = channelService.getPayClient(channel.getId()); + PayClient client = channelService.getPayClient(channel.getId()); // 2. 插入 PayOrderExtensionDO String no = noRedisDAO.generate(payProperties.getOrderNoPrefix()); @@ -237,7 +237,7 @@ public class PayOrderServiceImpl implements PayOrderService { appService.validPayApp(appId); // 校验支付渠道是否有效 PayChannelDO channel = channelService.validPayChannel(appId, channelCode); - PayClient client = channelService.getPayClient(channel.getId()); + PayClient client = channelService.getPayClient(channel.getId()); if (client == null) { log.error("[validatePayChannelCanSubmit][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); throw exception(CHANNEL_NOT_FOUND); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 57ada01bc2..1885cad649 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -98,7 +98,7 @@ public class PayRefundServiceImpl implements PayRefundService { PayOrderDO order = validatePayOrderCanRefund(reqDTO, app.getId()); // 1.3 校验支付渠道是否有效 PayChannelDO channel = channelService.validPayChannel(order.getChannelId()); - PayClient client = channelService.getPayClient(channel.getId()); + PayClient client = channelService.getPayClient(channel.getId()); if (client == null) { log.error("[refund][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); throw exception(CHANNEL_NOT_FOUND); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index b62670f496..7169d1a807 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java @@ -52,6 +52,13 @@ public interface PayTransferService { */ int syncTransfer(); + /** + * 【单个】同步渠道转账单状态 + * + * @param id 转账单编号 + */ + void syncTransfer(Long id); + /** * 渠道的转账通知 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index b3fd122e13..c8f3a480e4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -68,7 +68,7 @@ public class PayTransferServiceImpl implements PayTransferService { PayAppDO payApp = appService.validPayApp(reqDTO.getAppKey()); // 1.2 校验支付渠道是否有效 PayChannelDO channel = channelService.validPayChannel(payApp.getId(), reqDTO.getChannelCode()); - PayClient client = channelService.getPayClient(channel.getId()); + PayClient client = channelService.getPayClient(channel.getId()); if (client == null) { log.error("[createTransfer][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); throw exception(CHANNEL_NOT_FOUND); @@ -273,10 +273,19 @@ public class PayTransferServiceImpl implements PayTransferService { return count; } + @Override + public void syncTransfer(Long id) { + PayTransferDO transfer = transferMapper.selectById(id); + if (transfer == null) { + throw exception(PAY_TRANSFER_NOT_FOUND); + } + syncTransfer(transfer); + } + private boolean syncTransfer(PayTransferDO transfer) { try { // 1. 查询转账订单信息 - PayClient payClient = channelService.getPayClient(transfer.getChannelId()); + PayClient payClient = channelService.getPayClient(transfer.getChannelId()); if (payClient == null) { log.error("[syncTransfer][渠道编号({}) 找不到对应的支付客户端]", transfer.getChannelId()); return false; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java index 229e717957..fe8dbc3b7a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java @@ -311,7 +311,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest { .thenReturn(mockClient); // 调用 - PayClient client = channelService.getPayClient(id); + PayClient client = channelService.getPayClient(id); // 断言 assertSame(client, mockClient); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java index 7fa0c8d908..290aaa5fd7 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java @@ -350,7 +350,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode()))) .thenReturn(channel); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法() PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> @@ -404,7 +404,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { when(channelService.validPayChannel(eq(1L), eq(PayChannelEnum.ALIPAY_APP.getCode()))) .thenReturn(channel); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(支付渠道的调用) PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null) @@ -462,7 +462,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient 已支付) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()))); @@ -481,7 +481,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { o -> o.setOrderId(id).setStatus(PayOrderStatusEnum.WAITING.getStatus())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient 已支付) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); @@ -873,7 +873,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setCreateTime(LocalDateTime.now())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 异常) when(client.getOrder(any())).thenThrow(new RuntimeException()); @@ -900,7 +900,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setCreateTime(LocalDateTime.now())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 成功返回) PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, @@ -934,7 +934,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setCreateTime(LocalDateTime.now())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 成功返回) PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, @@ -965,7 +965,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setOrderId(order.getId())); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // 调用 @@ -1012,7 +1012,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setChannelId(10L)); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 退款返回) PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, @@ -1046,7 +1046,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setChannelId(10L)); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 成功返回) PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, @@ -1080,7 +1080,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { .setChannelId(10L)); orderExtensionMapper.insert(orderExtension); // mock 方法(PayClient) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(PayClient 关闭返回) PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java index adbf480d2a..5bfbd64177 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java @@ -331,7 +331,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { .setCode(PayChannelEnum.ALIPAY_APP.getCode())); when(channelService.validPayChannel(eq(1L))).thenReturn(channel); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 数据(refund 已存在) PayRefundDO refund = randomPojo(PayRefundDO.class, o -> @@ -363,7 +363,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { .setCode(PayChannelEnum.ALIPAY_APP.getCode())); when(channelService.validPayChannel(eq(10L))).thenReturn(channel); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(client 调用发生异常) when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException()); @@ -407,7 +407,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { .setCode(PayChannelEnum.ALIPAY_APP.getCode())); when(channelService.validPayChannel(eq(10L))).thenReturn(channel); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(client 成功) PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class); @@ -664,7 +664,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { .setOrderNo("P110").setNo("R220")); refundMapper.insert(refund); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(client 返回指定状态) PayRefundRespDTO respDTO = randomPojo(PayRefundRespDTO.class, o -> o.setStatus(status)); @@ -686,7 +686,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { .setOrderNo("P110").setNo("R220")); refundMapper.insert(refund); // mock 方法(client) - PayClient client = mock(PayClient.class); + PayClient client = mock(PayClient.class); when(channelService.getPayClient(eq(10L))).thenReturn(client); // mock 方法(client 抛出异常) when(client.getRefund(eq("P110"), eq("R220"))).thenThrow(new RuntimeException()); diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java index 9c9bce14fd..37c9e90c25 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java @@ -42,7 +42,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建客户端 Long channelId = RandomUtil.randomLong(); payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config); - PayClient client = payClientFactory.getPayClient(channelId); + PayClient client = payClientFactory.getPayClient(channelId); // 发起支付 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO(); // CommonResult result = client.unifiedOrder(reqDTO); @@ -65,7 +65,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建客户端 Long channelId = RandomUtil.randomLong(); payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.WX_PUB.getCode(), config); - PayClient client = payClientFactory.getPayClient(channelId); + PayClient client = payClientFactory.getPayClient(channelId); // 发起支付 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO(); // CommonResult result = client.unifiedOrder(reqDTO); @@ -88,7 +88,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建客户端 Long channelId = RandomUtil.randomLong(); payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config); - PayClient client = payClientFactory.getPayClient(channelId); + PayClient client = payClientFactory.getPayClient(channelId); // 发起支付 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO(); reqDTO.setNotifyUrl("http://yunai.natapp1.cc/admin-api/pay/notify/callback/18"); // TODO @tina: 这里改成你的 natapp 回调地址 @@ -112,7 +112,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建客户端 Long channelId = RandomUtil.randomLong(); payClientFactory.createOrUpdatePayClient(channelId, PayChannelEnum.ALIPAY_WAP.getCode(), config); - PayClient client = payClientFactory.getPayClient(channelId); + PayClient client = payClientFactory.getPayClient(channelId); // 发起支付 PayOrderUnifiedReqDTO reqDTO = buildPayOrderUnifiedReqDTO(); // CommonResult result = client.unifiedOrder(reqDTO); From 7c38a32fc9be07d7c1ef8e1ceb64d750f948176c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 May 2025 17:11:38 +0800 Subject: [PATCH 17/19] =?UTF-8?q?fix=EF=BC=9A=E3=80=90MALL=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=8F=91=E8=B4=A7?= =?UTF-8?q?=EF=BC=8CuploadTime=20=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/date/LocalDateTimeUtils.java | 6 ++++++ .../service/brokerage/BrokerageWithdrawServiceImpl.java | 2 +- .../system/service/social/SocialClientServiceImpl.java | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index c3b3b53fbb..6d19a3cc75 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -8,12 +8,16 @@ import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum; import java.time.*; +import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; import java.util.List; +import static cn.hutool.core.date.DatePattern.UTC_MS_WITH_XXX_OFFSET_PATTERN; +import static cn.hutool.core.date.DatePattern.createFormatter; + /** * 时间工具类,用于 {@link java.time.LocalDateTime} * @@ -26,6 +30,8 @@ public class LocalDateTimeUtils { */ public static LocalDateTime EMPTY = buildTime(1970, 1, 1); + public static DateTimeFormatter UTC_MS_WITH_XXX_OFFSET_FORMATTER = createFormatter(UTC_MS_WITH_XXX_OFFSET_PATTERN); + /** * 解析时间 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index ff258bb698..a873927f6c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -136,7 +136,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.ALIPAY_API.getType())) { channelCode = PayChannelEnum.ALIPAY_PC.getCode(); } else if (Objects.equal(withdraw.getType(), BrokerageWithdrawTypeEnum.WECHAT_API.getType())) { - channelCode = PayChannelEnum.WX_LITE.getCode(); + channelCode = withdraw.getTransferChannelCode(); userAccount = withdraw.getUserAccount(); // 特殊:微信需要有报备信息 channelExtras = PayTransferCreateReqDTO.buildWeiXinChannelExtra1000("佣金提现", "佣金提现"); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java index c25a28d676..b5c9d88a71 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java @@ -60,14 +60,14 @@ import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.time.Duration; -import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.util.List; import java.util.Map; import java.util.Objects; -import static cn.hutool.core.date.DatePattern.UTC_MS_WITH_XXX_OFFSET_PATTERN; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.UTC_MS_WITH_XXX_OFFSET_FORMATTER; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static java.util.Collections.singletonList; @@ -359,7 +359,7 @@ public class SocialClientServiceImpl implements SocialClientService { .deliveryMode(1) // 统一发货 .shippingList(shippingList) .payer(PayerBean.builder().openid(reqDTO.getOpenid()).build()) - .uploadTime(LocalDateTimeUtil.format(LocalDateTime.now(), UTC_MS_WITH_XXX_OFFSET_PATTERN)) + .uploadTime(ZonedDateTime.now().format(UTC_MS_WITH_XXX_OFFSET_FORMATTER)) .build(); try { WxMaOrderShippingInfoBaseResponse response = service.getWxMaOrderShippingService().upload(request); From 51c10914304c32ce0abc3bc2629ed91358bc4ddc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 11 May 2025 20:48:51 +0800 Subject: [PATCH 18/19] =?UTF-8?q?fix=EF=BC=9A=E3=80=90PAY=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91PayDemoWithdrawServiceImpl=20=E6=8B=BC?= =?UTF-8?q?=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...TransferServiceImpl.java => PayDemoWithdrawServiceImpl.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/{PayDemoTransferServiceImpl.java => PayDemoWithdrawServiceImpl.java} (99%) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java similarity index 99% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java index de08f8ecb5..b1a3b91516 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java @@ -35,7 +35,7 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; @Service @Validated @Slf4j -public class PayDemoTransferServiceImpl implements PayDemoWithdrawService { +public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { /** * 接入的支付应用标识 From 50e31f1bec9686e94b1c4b8b5eace76151635815 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 12 May 2025 09:10:21 +0800 Subject: [PATCH 19/19] =?UTF-8?q?feat=EF=BC=9A=E5=90=8C=E6=AD=A5=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E8=8F=9C=E5=8D=95=20sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 117 +++++++++++++++++------------------- 1 file changed, 55 insertions(+), 62 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index cceeab3be4..cdbaa0d064 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -11,7 +11,7 @@ Target Server Version : 80200 (8.2.0) File Encoding : 65001 - Date: 23/04/2025 23:07:47 + Date: 12/05/2025 09:09:45 */ SET NAMES utf8mb4; @@ -91,7 +91,7 @@ CREATE TABLE `infra_api_error_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 21559 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; +) ENGINE = InnoDB AUTO_INCREMENT = 22175 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; -- ---------------------------- -- Records of infra_api_error_log @@ -193,7 +193,7 @@ CREATE TABLE `infra_config` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '参数配置表'; +) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '参数配置表'; -- ---------------------------- -- Records of infra_config @@ -206,6 +206,7 @@ INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `val INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (10, 'url', 2, 'Swagger 接口文档的地址', 'url.swagger', '', b'1', '', '1', '2023-04-07 13:41:16', '1', '2023-04-07 14:59:00', b'0'); INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'ui', 2, '腾讯地图 key', 'tencent.lbs.key', 'TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E', b'1', '腾讯地图 key', '1', '2023-06-03 19:16:27', '1', '2023-06-03 19:16:27', b'0'); INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (12, 'test2', 2, 'test3', 'test4', 'test5', b'1', 'test6', '1', '2023-12-03 09:55:16', '1', '2025-04-06 21:00:09', b'0'); +INSERT INTO `infra_config` (`id`, `category`, `type`, `name`, `config_key`, `value`, `visible`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (13, '用户管理-账号初始密码', 2, '用户管理-注册开关', 'system.user.register-enabled', 'true', b'0', '', '1', '2025-04-26 17:23:41', '1', '2025-04-26 17:23:41', b'0'); COMMIT; -- ---------------------------- @@ -250,7 +251,7 @@ CREATE TABLE `infra_file` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1700 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; +) ENGINE = InnoDB AUTO_INCREMENT = 1898 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; -- ---------------------------- -- Records of infra_file @@ -275,19 +276,21 @@ CREATE TABLE `infra_file_config` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表'; +) ENGINE = InnoDB AUTO_INCREMENT = 31 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件配置表'; -- ---------------------------- -- Records of infra_file_config -- ---------------------------- BEGIN; -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\"}', '1', '2024-01-13 22:11:12', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:03:22', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:47:08', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\"}', '1', '2024-11-09 16:56:42', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\"}', '1', '2024-11-09 17:18:41', '1', '2025-04-07 09:15:02', b'0'); -INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\"}', '1', '2024-11-09 17:43:10', '1', '2025-04-07 09:15:02', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false}', '1', '2024-01-13 22:11:12', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\"}', '1', '2024-11-09 16:03:22', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 16:47:08', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 16:56:42', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 17:18:41', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\",\"enablePathStyleAccess\":false}', '1', '2024-11-09 17:43:10', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (29, '本地存储(示例)', 10, '仅适合 mac 或 windows', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig\",\"basePath\":\"/Users/yunai/tmp/file\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2025-05-02 11:25:45', '1', '2025-05-02 18:30:28', b'0'); +INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (30, 'SFTP 存储(示例)', 12, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig\",\"basePath\":\"/upload\",\"domain\":\"http://127.0.0.1:48080\",\"host\":\"127.0.0.1\",\"port\":2222,\"username\":\"foo\",\"password\":\"pass\"}', '1', '2025-05-02 16:34:10', '1', '2025-05-02 18:30:28', b'0'); COMMIT; -- ---------------------------- @@ -305,7 +308,7 @@ CREATE TABLE `infra_file_content` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 283 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; +) ENGINE = InnoDB AUTO_INCREMENT = 286 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; -- ---------------------------- -- Records of infra_file_content @@ -333,7 +336,7 @@ CREATE TABLE `infra_job` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表'; +) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表'; -- ---------------------------- -- Records of infra_job @@ -350,7 +353,8 @@ INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param` INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '访问日志清理 Job', 2, 'accessLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 10:59:41', '1', '2023-10-03 11:01:10', b'0'); INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '错误日志清理 Job', 2, 'errorLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:00:43', '1', '2023-10-03 11:01:12', b'0'); INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '任务日志清理 Job', 2, 'jobLogCleanJob', '', '0 0 0 * * ?', 3, 0, 0, '1', '2023-10-03 11:01:33', '1', '2024-09-12 13:40:34', b'0'); -INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (33, 'demoJob', 2, 'demoJob', '', '0 * * * * ?', 1, 1, 0, '1', '2024-10-27 19:38:46', '1', '2024-10-27 19:40:23', b'0'); +INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (33, 'demoJob', 2, 'demoJob', '', '0 * * * * ?', 1, 1, 0, '1', '2024-10-27 19:38:46', '1', '2025-05-10 18:13:54', b'0'); +INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (35, '转账订单的同步 Job', 2, 'payTransferSyncJob', '', '0 * * * * ?', 0, 0, 0, '1', '2025-05-10 17:35:54', '1', '2025-05-10 18:13:52', b'0'); COMMIT; -- ---------------------------- @@ -374,7 +378,7 @@ CREATE TABLE `infra_job_log` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 638 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表'; +) ENGINE = InnoDB AUTO_INCREMENT = 972 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表'; -- ---------------------------- -- Records of infra_job_log @@ -444,7 +448,7 @@ CREATE TABLE `system_dict_data` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3002 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表'; +) ENGINE = InnoDB AUTO_INCREMENT = 3003 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表'; -- ---------------------------- -- Records of system_dict_data @@ -666,8 +670,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1363, 3, '覆盖绑定', '3', 'brokerage_bind_mode', 0, '', '', '如果用户已经有推广人,推广人会被变更', '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1364, 1, '钱包', '1', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1365, 2, '银行卡', '2', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1366, 3, '微信', '3', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2024-10-13 11:06:54', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1367, 4, '支付宝', '4', 'brokerage_withdraw_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1366, 3, '微信收款码', '3', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2025-05-10 08:24:25', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1367, 4, '支付宝收款码', '4', 'brokerage_withdraw_type', 0, '', '', '手动打款', '', '2023-09-28 02:46:05', '1', '2025-05-10 08:24:37', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1368, 1, '订单返佣', '1', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1369, 2, '申请提现', '2', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1370, 3, '申请提现驳回', '3', 'brokerage_record_biz_type', 0, '', '', NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0'); @@ -764,13 +768,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1475, 2, '发短信', '2', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:48:31', '1', '2024-01-15 20:48:31', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1476, 3, '上门拜访', '3', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:07', '1', '2024-01-15 20:49:07', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1477, 4, '微信沟通', '4', 'crm_follow_up_type', 0, '', '', '', '1', '2024-01-15 20:49:15', '1', '2024-01-15 20:49:15', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1478, 4, '钱包余额', '4', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:37', '1', '2023-10-28 16:28:37', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1479, 3, '银行卡', '3', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:28:21', '1', '2023-10-28 16:28:21', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1480, 2, '微信余额', '2', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:07', '1', '2023-10-28 16:28:07', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1481, 1, '支付宝余额', '1', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:27:44', '1', '2023-10-28 16:27:44', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1482, 4, '转账失败', '30', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2023-10-28 16:24:16', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1483, 3, '转账成功', '20', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2023-10-28 16:23:50', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1484, 2, '转账进行中', '10', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2023-10-28 16:23:12', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1482, 4, '转账失败', '20', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2025-05-08 12:59:01', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1483, 3, '转账成功', '10', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2025-05-08 12:58:58', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1484, 2, '转账进行中', '5', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2025-05-08 12:58:54', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1485, 1, '等待转账', '0', 'pay_transfer_status', 0, 'default', '', '', '1', '2023-10-28 16:21:43', '1', '2023-10-28 16:23:22', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1486, 10, '其它入库', '10', 'erp_stock_record_biz_type', 0, '', '', '', '1', '2024-02-05 18:07:25', '1', '2024-02-05 18:07:43', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1487, 11, '其它入库(作废)', '11', 'erp_stock_record_biz_type', 0, 'danger', '', '', '1', '2024-02-05 18:08:07', '1', '2024-02-05 19:20:16', b'0'); @@ -869,7 +869,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1590, 20, 'SIMPLE 设计器', '20', 'bpm_model_type', 0, 'success', '', '', '1', '2024-08-26 15:22:27', '1', '2024-08-26 16:45:58', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1591, 4, '七牛云', 'QINIU', 'system_sms_channel_code', 0, '', '', '', '1', '2024-08-31 08:45:03', '1', '2024-08-31 08:45:24', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1592, 3, '新人券', '3', 'promotion_coupon_take_type', 0, 'info', '', '新人注册后,自动发放', '1', '2024-09-03 11:57:16', '1', '2024-09-03 11:57:28', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1593, 5, '微信零钱', '5', 'brokerage_withdraw_type', 0, '', '', '自动打款', '1', '2024-10-13 11:06:48', '1', '2024-10-13 11:06:59', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1593, 5, '微信零钱', '5', 'brokerage_withdraw_type', 0, '', '', 'API 打款', '1', '2024-10-13 11:06:48', '1', '2025-05-10 08:24:55', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1683, 10, '字节豆包', 'DouBao', 'ai_platform', 0, '', '', '', '1', '2025-02-23 19:51:40', '1', '2025-02-23 19:52:02', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1684, 11, '腾讯混元', 'HunYuan', 'ai_platform', 0, '', '', '', '1', '2025-02-23 20:58:04', '1', '2025-02-23 20:58:04', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1685, 12, '硅基流动', 'SiliconFlow', 'ai_platform', 0, '', '', '', '1', '2025-02-24 20:19:09', '1', '2025-02-24 20:19:09', b'0'); @@ -1055,7 +1055,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2172, 31, 'RABBITMQ', '31', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:47', '1', '2025-03-17 09:40:46', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2173, 32, 'KAFKA', '32', 'iot_data_bridge_type_enum', 0, 'primary', '', '', '1', '2025-03-09 12:41:59', '1', '2025-03-17 09:40:46', b'0'); INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3000, 16, '百川智能', 'BaiChuan', 'ai_platform', 0, '', '', '', '1', '2025-03-23 12:15:46', '1', '2025-03-23 12:15:46', b'0'); -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3001, 50, 'Vben5.0 Ant Design Schema 模版', '40', 'infra_codegen_front_type', 0, '', '', NULL, '1', '2025-04-23 21:47:47', '1', '2025-04-23 21:47:47', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3001, 50, 'Vben5.0 Ant Design Schema 模版', '40', 'infra_codegen_front_type', 0, '', '', NULL, '1', '2025-04-23 21:47:47', '1', '2025-05-02 12:01:15', b'0'); +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3002, 6, '支付宝余额', '6', 'brokerage_withdraw_type', 0, '', '', 'API 打款', '1', '2025-05-10 08:24:49', '1', '2025-05-10 08:24:49', b'0'); COMMIT; -- ---------------------------- @@ -1156,7 +1157,6 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (606, 'CRM 审批状态', 'crm_audit_status', 0, '', '1', '2023-11-30 18:56:23', '1', '2023-11-30 18:56:23', b'0', '1970-01-01 00:00:00'); INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (607, 'CRM 产品单位', 'crm_product_unit', 0, '', '1', '2023-12-05 23:01:51', '1', '2023-12-05 23:01:51', b'0', '1970-01-01 00:00:00'); INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (608, 'CRM 跟进方式', 'crm_follow_up_type', 0, '', '1', '2024-01-15 20:48:05', '1', '2024-01-15 20:48:05', b'0', '1970-01-01 00:00:00'); -INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (609, '支付转账类型', 'pay_transfer_type', 0, '', '1', '2023-10-28 16:27:18', '1', '2023-10-28 16:27:18', b'0', '1970-01-01 00:00:00'); INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (610, '转账订单状态', 'pay_transfer_status', 0, '', '1', '2023-10-28 16:18:32', '1', '2023-10-28 16:18:32', b'0', '1970-01-01 00:00:00'); INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (611, 'ERP 库存明细的业务类型', 'erp_stock_record_biz_type', 0, 'ERP 库存明细的业务类型', '1', '2024-02-05 18:07:02', '1', '2024-02-05 18:07:02', b'0', '1970-01-01 00:00:00'); INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (612, 'ERP 审批状态', 'erp_audit_status', 0, '', '1', '2024-02-06 00:00:07', '1', '2024-02-06 00:00:07', b'0', '1970-01-01 00:00:00'); @@ -1212,7 +1212,7 @@ CREATE TABLE `system_login_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3746 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; +) ENGINE = InnoDB AUTO_INCREMENT = 3822 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; -- ---------------------------- -- Records of system_login_log @@ -1343,7 +1343,7 @@ CREATE TABLE `system_menu` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 5008 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表'; +) ENGINE = InnoDB AUTO_INCREMENT = 5013 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表'; -- ---------------------------- -- Records of system_menu @@ -1486,15 +1486,9 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1150, '秘钥解析', '', 3, 6, 1129, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2021-11-08 15:15:47', '1', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1161, '退款订单', '', 2, 3, 1117, 'refund', 'fa:registered', 'pay/refund/index', 'PayRefund', 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '1', '2024-02-29 08:59:20', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1162, '退款订单查询', 'pay:refund:query', 3, 1, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1163, '退款订单创建', 'pay:refund:create', 3, 2, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1164, '退款订单更新', 'pay:refund:update', 3, 3, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1165, '退款订单删除', 'pay:refund:delete', 3, 4, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1166, '退款订单导出', 'pay:refund:export', 3, 5, 1161, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:29:07', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1173, '支付订单', '', 2, 2, 1117, 'order', 'fa:cc-paypal', 'pay/order/index', 'PayOrder', 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '1', '2024-02-29 08:59:43', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1174, '支付订单查询', 'pay:order:query', 3, 1, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1175, '支付订单创建', 'pay:order:create', 3, 2, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1176, '支付订单更新', 'pay:order:update', 3, 3, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1177, '支付订单删除', 'pay:order:delete', 3, 4, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1178, '支付订单导出', 'pay:order:export', 3, 5, 1173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-12-25 08:49:43', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1185, '工作流程', '', 1, 50, 0, '/bpm', 'fa:medium', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:26:36', '1', '2024-02-29 12:43:43', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1186, '流程管理', '', 1, 10, 1185, 'manager', 'fa:dedent', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-30 20:28:30', '1', '2024-02-29 12:36:02', b'0'); @@ -1541,7 +1535,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1241, '文件配置删除', 'infra:file-config:delete', 3, 4, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1242, '文件配置导出', 'infra:file-config:export', 3, 5, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, '文件管理', '', 2, 6, 2, 'file', 'ep:files', NULL, '', 0, b'1', b'1', b'1', '1', '2022-03-16 23:47:40', '1', '2024-04-23 00:02:11', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1254, '作者动态', '', 1, 0, 0, 'https://www.iocoder.cn', 'ep:avatar', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-04-23 01:03:15', '104', '2025-01-04 10:59:37', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1254, '作者动态', '', 1, 0, 0, 'https://www.iocoder.cn', 'ep:avatar', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-04-23 01:03:15', '1', '2025-04-29 17:45:38', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1255, '数据源配置', '', 2, 1, 2, 'data-source-config', 'ep:data-analysis', 'infra/dataSourceConfig/index', 'InfraDataSourceConfig', 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '1', '2024-02-29 08:51:25', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1256, '数据源配置查询', 'infra:data-source-config:query', 3, 1, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1257, '数据源配置创建', 'infra:data-source-config:create', 3, 2, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0'); @@ -1555,7 +1549,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1266, '客户端更新', 'system:oauth2-client:update', 3, 3, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:28', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1281, '报表管理', '', 2, 40, 0, '/report', 'ep:pie-chart', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2024-02-29 12:33:03', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'ep:trend-charts', 'report/jmreport/index', 'GoView', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2024-02-29 12:33:54', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'ep:trend-charts', 'report/jmreport/index', 'JimuReport', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2025-05-03 09:57:07', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 2362, 'product', 'fa:product-hunt', NULL, NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-09-30 11:52:36', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'ep:cellphone', 'mall/product/category/index', 'ProductCategory', 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-08-21 10:27:15', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); @@ -1688,7 +1682,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2150, '发送测试站内信', 'system:notify-template:send-notify', 3, 5, 2145, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-28 10:54:43', '1', '2023-01-28 10:54:43', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2151, '消息记录', '', 2, 0, 2144, 'notify-message', 'fa:edit', 'system/notify/message/index', 'SystemNotifyMessage', 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '1', '2024-02-29 08:49:22', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2152, '站内信消息查询', 'system:notify-message:query', 3, 1, 2151, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '', '2023-01-28 04:28:22', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2153, '大屏设计器', '', 2, 2, 1281, 'go-view', 'fa:area-chart', 'report/goview/index', 'JimuReport', 0, b'1', b'1', b'1', '1', '2023-02-07 00:03:19', '1', '2024-02-29 12:34:02', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2153, '大屏设计器', '', 2, 2, 1281, 'go-view', 'fa:area-chart', 'report/goview/index', 'GoView', 0, b'1', b'1', b'1', '1', '2023-02-07 00:03:19', '1', '2025-05-03 09:57:03', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2154, '创建项目', 'report:go-view-project:create', 3, 1, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:14', '1', '2023-02-07 19:25:14', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2155, '更新项目', 'report:go-view-project:update', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:34', '1', '2024-04-24 20:01:18', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0'); @@ -1931,7 +1925,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2547, '订单查询', 'trade:order:query', 3, 1, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:00', '1', '2024-01-16 08:52:00', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2548, '订单更新', 'trade:order:update', 3, 2, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-01-16 08:52:21', '1', '2024-01-16 08:52:21', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2549, '支付&退款案例', '', 2, 1, 2161, 'order', 'fa:paypal', 'pay/demo/order/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:45:00', '1', '2024-01-18 23:47:21', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2550, '转账案例', '', 2, 2, 2161, 'transfer', 'fa:transgender-alt', 'pay/demo/transfer/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:51:16', '1', '2024-01-18 23:51:16', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2550, '提现转账案例', '', 2, 2, 2161, 'transfer', 'fa:transgender-alt', 'pay/demo/withdraw/index', '', 0, b'1', b'1', b'1', '1', '2024-01-18 23:51:16', '1', '2025-05-08 13:04:36', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2551, '钱包管理', '', 1, 4, 1117, 'wallet', 'ep:wallet', '', '', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '1', '2024-02-29 08:58:54', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2552, '充值套餐', '', 2, 2, 2551, 'wallet-recharge-package', 'fa:leaf', 'pay/wallet/rechargePackage/index', 'WalletRechargePackage', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2553, '钱包充值套餐查询', 'pay:wallet-recharge-package:query', 3, 1, 2552, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0'); @@ -2256,12 +2250,16 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4054, 'IoT 数据桥梁更新', 'iot:data-bridge:update', 3, 3, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:11', '', '2025-03-09 13:47:11', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4055, 'IoT 数据桥梁删除', 'iot:data-bridge:delete', 3, 4, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4056, 'IoT 数据桥梁导出', 'iot:data-bridge:export', 3, 5, 4051, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2025-03-09 13:47:12', '', '2025-03-09 13:47:12', b'0'); -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5000, 'AI 工作流', '', 2, 5, 2758, 'workflow', 'fa:hand-grab-o', 'ai/workflow/index.vue', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:50:27', '1', '2025-03-30 10:24:52', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5000, 'AI 工作流', '', 2, 5, 2758, 'workflow', 'fa:hand-grab-o', 'ai/workflow/index.vue', 'AiWorkflow', 0, b'1', b'1', b'1', '1', '2025-03-25 09:50:27', '1', '2025-05-03 18:55:12', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5001, 'AI 工作流查询', 'ai:workflow:query', 3, 1, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:11', '1', '2025-03-25 09:51:11', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5002, 'AI 工作流创建', 'ai:workflow:create', 3, 2, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:28', '1', '2025-03-25 09:51:28', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5003, 'AI 工作流更新', 'ai:workflow:update', 3, 3, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:42', '1', '2025-03-25 09:51:42', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5004, 'AI 工作流删除', 'ai:workflow:delete', 3, 4, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-25 09:51:55', '1', '2025-03-25 09:52:03', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5005, 'AI 工作流测试', 'ai:workflow:test', 3, 5, 5000, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-03-30 10:29:41', '1', '2025-03-30 10:29:41', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5009, '仪表盘设计器', '', 2, 1, 1281, 'jimu-bi', 'fa:y-combinator', 'report/jmreport/bi', 'JimuBI', 0, b'1', b'1', b'1', '1', '2025-05-03 09:57:15', '1', '2025-05-03 10:02:05', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5010, '租户切换', 'system:tenant:visit', 3, 999, 1138, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-05 15:25:32', '1', '2025-05-05 15:25:32', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5011, '转账订单查询', 'pay:transfer:query', 3, 1, 2559, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-08 12:46:53', '1', '2025-05-08 12:46:53', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5012, '转账订单导出', 'pay:transfer:export', 3, 2, 2559, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-05-10 17:00:28', '1', '2025-05-10 17:00:28', b'0'); COMMIT; -- ---------------------------- @@ -2383,7 +2381,7 @@ CREATE TABLE `system_oauth2_access_token` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_access_token`(`access_token` ASC) USING BTREE, INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 15215 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; +) ENGINE = InnoDB AUTO_INCREMENT = 16697 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; -- ---------------------------- -- Records of system_oauth2_access_token @@ -2451,10 +2449,10 @@ CREATE TABLE `system_oauth2_client` ( -- Records of system_oauth2_client -- ---------------------------- BEGIN; -INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/a5e2e244368878a366b516805a4aabf1.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2025-03-27 10:30:12', b'0'); -INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/277a899d573723f1fcdfb57340f00379.png', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2025-04-06 19:45:45', b'0'); -INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/fe4ed36596adad5120036ef61a6d0153654544d44af8dd4ad3ffe8f759933d6f.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2025-04-06 19:39:40', b'0'); -INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/604bdc695e13b3b22745be704d1f2aa8ee05c5f26f9fead6d1ca49005afbc857.jpeg', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2022-10-04 20:31:21', b'0'); +INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/20250502/sort2_1746189740718.png', '我是描述', 0, 1800, 2592000, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2025-05-02 20:42:22', b'0'); +INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/xx/20250502/ed07110a37464b5299f8bd7c67ad65c7_1746187077009.jpg', '啦啦啦啦', 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2025-05-02 19:58:08', b'0'); +INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (41, 'yudao-sso-demo-by-code', 'test', '基于授权码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/it/20250502/sign_1746181948685.png', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"authorization_code\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-09-29 13:28:31', '1', '2025-05-02 18:32:30', b'0'); +INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (42, 'yudao-sso-demo-by-password', 'test', '基于密码模式,如何实现 SSO 单点登录?', 'http://test.yudao.iocoder.cn/604bdc695e13b3b22745be704d1f2aa8ee05c5f26f9fead6d1ca49005afbc857.jpeg', NULL, 0, 1800, 43200, '[\"http://127.0.0.1:18080\"]', '[\"password\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[]', '[]', NULL, '1', '2022-10-04 17:40:16', '1', '2025-05-04 16:00:46', b'0'); COMMIT; -- ---------------------------- @@ -2505,7 +2503,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1983 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; +) ENGINE = InnoDB AUTO_INCREMENT = 2036 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; -- ---------------------------- -- Records of system_oauth2_refresh_token @@ -2539,7 +2537,7 @@ CREATE TABLE `system_operate_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 9088 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本'; +) ENGINE = InnoDB AUTO_INCREMENT = 9090 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本'; -- ---------------------------- -- Records of system_operate_log @@ -2607,7 +2605,7 @@ BEGIN; INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '超级管理员', 'super_admin', 1, 1, '', 0, 1, '超级管理员', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:21', b'0', 1); INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '普通角色', 'common', 2, 2, '', 0, 1, '普通角色', 'admin', '2021-01-05 17:03:48', '', '2022-02-22 05:08:20', b'0', 1); INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 'CRM 管理员', 'crm_admin', 2, 1, '', 0, 1, 'CRM 专属角色', '1', '2024-02-24 10:51:13', '1', '2024-02-24 02:51:32', b'0', 1); -INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '123', '', '2021-01-06 13:49:35', '1', '2025-04-03 07:42:30', b'0', 1); +INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '测试账号', 'test', 0, 1, '[]', 0, 2, '123', '', '2021-01-06 13:49:35', '1', '2025-04-30 17:38:28', b'0', 1); INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121); INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122); INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (155, '测试数据权限', 'test-dp', 3, 2, '[100,102,103,104,105,108]', 0, 2, '', '1', '2025-03-31 14:58:06', '1', '2025-04-17 23:07:44', b'0', 1); @@ -2629,7 +2627,7 @@ CREATE TABLE `system_role_menu` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 6138 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表'; +) ENGINE = InnoDB AUTO_INCREMENT = 6139 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表'; -- ---------------------------- -- Records of system_role_menu @@ -2954,15 +2952,9 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2080, 2, 1150, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2081, 2, 1161, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2082, 2, 1162, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2083, 2, 1163, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2084, 2, 1164, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2085, 2, 1165, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2086, 2, 1166, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2087, 2, 1173, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2088, 2, 1174, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2089, 2, 1175, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2090, 2, 1176, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); -INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2091, 2, 1177, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2092, 2, 1178, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2099, 2, 1226, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2100, 2, 1227, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1); @@ -3503,6 +3495,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6135, 155, 4017, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6136, 155, 4018, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1); INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6137, 155, 4031, '1', '2025-04-01 13:49:30', '1', '2025-04-01 13:49:30', b'0', 1); +INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6138, 101, 5010, '1', '2025-05-05 17:49:17', '1', '2025-05-05 17:49:17', b'0', 1); COMMIT; -- ---------------------------- @@ -3557,7 +3550,7 @@ CREATE TABLE `system_sms_code` ( `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号' -) ENGINE = InnoDB AUTO_INCREMENT = 657 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; +) ENGINE = InnoDB AUTO_INCREMENT = 666 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; -- ---------------------------- -- Records of system_sms_code @@ -3598,7 +3591,7 @@ CREATE TABLE `system_sms_log` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1281 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志'; +) ENGINE = InnoDB AUTO_INCREMENT = 1290 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志'; -- ---------------------------- -- Records of system_sms_log @@ -3731,7 +3724,7 @@ CREATE TABLE `system_social_user_bind` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 156 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表'; +) ENGINE = InnoDB AUTO_INCREMENT = 164 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表'; -- ---------------------------- -- Records of system_social_user_bind @@ -3901,7 +3894,7 @@ CREATE TABLE `system_users` ( -- Records of system_users -- ---------------------------- BEGIN; -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$KljJDa/LK7QfDm0lF5OhuePhlPfjRH3tB2Wu351Uidz.oQGJXevPi', '芋道源码', '管理员', 103, '[1,2]', '11aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/f5660f0f8998e8d89f2d742fedee7cbb7e85ecc505bd33b3cc0f75b6a0395931.png', 0, '0:0:0:0:0:0:0:1', '2025-04-23 12:46:09', 'admin', '2021-01-05 17:03:47', NULL, '2025-04-23 12:46:09', b'0', 1); +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$KljJDa/LK7QfDm0lF5OhuePhlPfjRH3tB2Wu351Uidz.oQGJXevPi', '芋道源码', '管理员', 103, '[1,2]', '11aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/test/20250502/avatar_1746154660449.png', 0, '0:0:0:0:0:0:0:1', '2025-05-10 18:03:15', 'admin', '2021-01-05 17:03:47', NULL, '2025-05-10 18:03:15', b'0', 1); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$h.aaPKgO.odHepnk5PCsWeEwKdojFWdTItxGKfx1r0e1CSeBzsTJ6', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-04-08 09:36:40', '', '2021-01-07 09:07:17', NULL, '2025-04-21 14:23:08', b'0', 1); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$fUBSmjKCPYAUmnMzOb6qE.eZCGPhHi1JmAKclODbfS/O7fHOl2bH6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-08-11 17:48:12', '', '2021-01-13 23:50:35', NULL, '2025-04-21 14:23:08', b'0', 1); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-03-28 20:01:16', '', '2021-01-21 02:13:53', NULL, '2025-04-21 14:23:08', b'0', 1); @@ -3911,7 +3904,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-07-20 22:23:17', '1', '2022-02-22 00:56:14', NULL, '2025-04-21 14:23:08', b'0', 121); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:42:17', '110', '2022-02-23 13:14:33', NULL, '2025-04-21 14:23:08', b'0', 121); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-16 23:11:38', '1', '2022-02-23 19:08:03', NULL, '2025-04-21 14:23:08', b'0', 1); -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2025-04-21 14:23:08', b'0', 122); +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道1', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', '1', '2025-05-05 15:30:53', b'0', 122); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-03-24 22:21:05', '1', '2022-03-19 21:50:58', NULL, '2025-04-21 14:23:08', b'0', 1); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, NULL, 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2025-04-21 14:23:08', b'0', 1); INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$04$sEtimsHu9YCkYY4/oqElHem2Ijc9ld20eYO6lN.g/21NfLUTDLB9W', '测试号02', '1111', 100, '[2]', '', '15601691234', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2024-10-02 10:16:20', '1', '2022-07-09 17:40:26', NULL, '2025-04-21 14:23:08', b'0', 1);