Commit cbc7b9dfc0e9ab56b6815f412a2f49751265a9e7

Authored by xingyu4j
1 parent 24439b70

refactor: pay

yudao-ui-admin-vue3/src/api/pay/app/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { AppVO } from './types' 2 +
  3 +export interface AppVO {
  4 + id: number
  5 + name: string
  6 + status: number
  7 + remark: string
  8 + payNotifyUrl: string
  9 + refundNotifyUrl: string
  10 + merchantId: number
  11 + merchantName: string
  12 + createTime: Date
  13 +}
  14 +
  15 +export interface AppPageReqVO extends PageParam {
  16 + name?: string
  17 + status?: number
  18 + remark?: string
  19 + payNotifyUrl?: string
  20 + refundNotifyUrl?: string
  21 + merchantName?: string
  22 + createTime?: Date[]
  23 +}
  24 +
  25 +export interface AppExportReqVO {
  26 + name?: string
  27 + status?: number
  28 + remark?: string
  29 + payNotifyUrl?: string
  30 + refundNotifyUrl?: string
  31 + merchantName?: string
  32 + createTime?: Date[]
  33 +}
  34 +
  35 +export interface AppUpdateStatusReqVO {
  36 + id: number
  37 + status: number
  38 +}
3 39
4 // 查询列表支付应用 40 // 查询列表支付应用
5 -export const getAppPageApi = (params) => { 41 +export const getAppPageApi = (params: AppPageReqVO) => {
6 return request.get({ url: '/pay/app/page', params }) 42 return request.get({ url: '/pay/app/page', params })
7 } 43 }
8 44
@@ -22,11 +58,7 @@ export const updateAppApi = (data: AppVO) => { @@ -22,11 +58,7 @@ export const updateAppApi = (data: AppVO) => {
22 } 58 }
23 59
24 // 支付应用信息状态修改 60 // 支付应用信息状态修改
25 -export const changeAppStatusApi = (id: number, status: number) => {  
26 - const data = {  
27 - id,  
28 - status  
29 - } 61 +export const changeAppStatusApi = (data: AppUpdateStatusReqVO) => {
30 return request.put({ url: '/pay/app/update-status', data: data }) 62 return request.put({ url: '/pay/app/update-status', data: data })
31 } 63 }
32 64
@@ -36,7 +68,7 @@ export const deleteAppApi = (id: number) => { @@ -36,7 +68,7 @@ export const deleteAppApi = (id: number) => {
36 } 68 }
37 69
38 // 导出支付应用 70 // 导出支付应用
39 -export const exportAppApi = (params) => { 71 +export const exportAppApi = (params: AppExportReqVO) => {
40 return request.download({ url: '/pay/app/export-excel', params }) 72 return request.download({ url: '/pay/app/export-excel', params })
41 } 73 }
42 74
yudao-ui-admin-vue3/src/api/pay/app/types.ts deleted
1 -export type AppVO = {  
2 - id: number  
3 - name: string  
4 - status: number  
5 - remark: string  
6 - payNotifyUrl: string  
7 - refundNotifyUrl: string  
8 - merchantName: string  
9 - merchantId: number  
10 - createTime: string  
11 -}  
yudao-ui-admin-vue3/src/api/pay/channel/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { ChannelVO } from './types' 2 +
  3 +export interface ChannelVO {
  4 + id: number
  5 + code: string
  6 + config: string
  7 + status: number
  8 + remark: string
  9 + feeRate: number
  10 + merchantId: number
  11 + appId: number
  12 + createTime: Date
  13 +}
  14 +
  15 +export interface ChannelPageReqVO extends PageParam {
  16 + code?: string
  17 + status?: number
  18 + remark?: string
  19 + feeRate?: number
  20 + merchantId?: number
  21 + appId?: number
  22 + config?: string
  23 + createTime?: Date[]
  24 +}
  25 +
  26 +export interface ChannelExportReqVO {
  27 + code?: string
  28 + status?: number
  29 + remark?: string
  30 + feeRate?: number
  31 + merchantId?: number
  32 + appId?: number
  33 + config?: string
  34 + createTime?: Date[]
  35 +}
3 36
4 // 查询列表支付渠道 37 // 查询列表支付渠道
5 -export const getChannelPageApi = (params) => { 38 +export const getChannelPageApi = (params: ChannelPageReqVO) => {
6 return request.get({ url: '/pay/channel/page', params }) 39 return request.get({ url: '/pay/channel/page', params })
7 } 40 }
8 41
@@ -32,6 +65,6 @@ export const deleteChannelApi = (id: number) => { @@ -32,6 +65,6 @@ export const deleteChannelApi = (id: number) => {
32 } 65 }
33 66
34 // 导出支付渠道 67 // 导出支付渠道
35 -export const exportChannelApi = (params) => { 68 +export const exportChannelApi = (params: ChannelExportReqVO) => {
36 return request.download({ url: '/pay/channel/export-excel', params }) 69 return request.download({ url: '/pay/channel/export-excel', params })
37 } 70 }
yudao-ui-admin-vue3/src/api/pay/channel/types.ts deleted
1 -export type ChannelVO = {  
2 - id: number  
3 - code: string  
4 - config: string  
5 - status: number  
6 - remark: string  
7 - feeRate: number  
8 - merchantId: number  
9 - appId: number  
10 - createTime: string  
11 -}  
yudao-ui-admin-vue3/src/api/pay/merchant/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { MerchantVO } from './types' 2 +
  3 +export interface MerchantVO {
  4 + id: number
  5 + no: string
  6 + name: string
  7 + shortName: string
  8 + status: number
  9 + remark: string
  10 + createTime: Date
  11 +}
  12 +
  13 +export interface MerchantPageReqVO extends PageParam {
  14 + no?: string
  15 + name?: string
  16 + shortName?: string
  17 + status?: number
  18 + remark?: string
  19 + createTime?: Date[]
  20 +}
  21 +
  22 +export interface MerchantExportReqVO {
  23 + no?: string
  24 + name?: string
  25 + shortName?: string
  26 + status?: number
  27 + remark?: string
  28 + createTime?: Date[]
  29 +}
3 30
4 // 查询列表支付商户 31 // 查询列表支付商户
5 -export const getMerchantPageApi = (params) => { 32 +export const getMerchantPageApi = (params: MerchantPageReqVO) => {
6 return request.get({ url: '/pay/merchant/page', params }) 33 return request.get({ url: '/pay/merchant/page', params })
7 } 34 }
8 35
@@ -37,7 +64,7 @@ export const deleteMerchantApi = (id: number) => { @@ -37,7 +64,7 @@ export const deleteMerchantApi = (id: number) => {
37 } 64 }
38 65
39 // 导出支付商户 66 // 导出支付商户
40 -export const exportMerchantApi = (params) => { 67 +export const exportMerchantApi = (params: MerchantExportReqVO) => {
41 return request.download({ url: '/pay/merchant/export-excel', params }) 68 return request.download({ url: '/pay/merchant/export-excel', params })
42 } 69 }
43 // 支付商户状态修改 70 // 支付商户状态修改
yudao-ui-admin-vue3/src/api/pay/merchant/types.ts deleted
1 -export type MerchantVO = {  
2 - id: number  
3 - no: string  
4 - name: string  
5 - shortName: string  
6 - status: number  
7 - remark: string  
8 - createTime: string  
9 -}  
yudao-ui-admin-vue3/src/api/pay/order/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { OrderVO } from './types' 2 +
  3 +export interface OrderVO {
  4 + id: number
  5 + merchantId: number
  6 + appId: number
  7 + channelId: number
  8 + channelCode: string
  9 + merchantOrderId: string
  10 + subject: string
  11 + body: string
  12 + notifyUrl: string
  13 + notifyStatus: number
  14 + amount: number
  15 + channelFeeRate: number
  16 + channelFeeAmount: number
  17 + status: number
  18 + userIp: string
  19 + expireTime: Date
  20 + successTime: Date
  21 + notifyTime: Date
  22 + successExtensionId: number
  23 + refundStatus: number
  24 + refundTimes: number
  25 + refundAmount: number
  26 + channelUserId: string
  27 + channelOrderNo: string
  28 + createTime: Date
  29 +}
  30 +
  31 +export interface OrderPageReqVO extends PageParam {
  32 + merchantId?: number
  33 + appId?: number
  34 + channelId?: number
  35 + channelCode?: string
  36 + merchantOrderId?: string
  37 + subject?: string
  38 + body?: string
  39 + notifyUrl?: string
  40 + notifyStatus?: number
  41 + amount?: number
  42 + channelFeeRate?: number
  43 + channelFeeAmount?: number
  44 + status?: number
  45 + expireTime?: Date[]
  46 + successTime?: Date[]
  47 + notifyTime?: Date[]
  48 + successExtensionId?: number
  49 + refundStatus?: number
  50 + refundTimes?: number
  51 + channelUserId?: string
  52 + channelOrderNo?: string
  53 + createTime?: Date[]
  54 +}
  55 +
  56 +export interface OrderExportReqVO {
  57 + merchantId?: number
  58 + appId?: number
  59 + channelId?: number
  60 + channelCode?: string
  61 + merchantOrderId?: string
  62 + subject?: string
  63 + body?: string
  64 + notifyUrl?: string
  65 + notifyStatus?: number
  66 + amount?: number
  67 + channelFeeRate?: number
  68 + channelFeeAmount?: number
  69 + status?: number
  70 + expireTime?: Date[]
  71 + successTime?: Date[]
  72 + notifyTime?: Date[]
  73 + successExtensionId?: number
  74 + refundStatus?: number
  75 + refundTimes?: number
  76 + channelUserId?: string
  77 + channelOrderNo?: string
  78 + createTime?: Date[]
  79 +}
3 80
4 // 查询列表支付订单 81 // 查询列表支付订单
5 -export const getOrderPageApi = async (params) => { 82 +export const getOrderPageApi = async (params: OrderPageReqVO) => {
6 return await request.get({ url: '/pay/order/page', params }) 83 return await request.get({ url: '/pay/order/page', params })
7 } 84 }
8 85
@@ -27,6 +104,6 @@ export const deleteOrderApi = async (id: number) => { @@ -27,6 +104,6 @@ export const deleteOrderApi = async (id: number) => {
27 } 104 }
28 105
29 // 导出支付订单 106 // 导出支付订单
30 -export const exportOrderApi = async (params) => { 107 +export const exportOrderApi = async (params: OrderExportReqVO) => {
31 return await request.download({ url: '/pay/order/export-excel', params }) 108 return await request.download({ url: '/pay/order/export-excel', params })
32 } 109 }
yudao-ui-admin-vue3/src/api/pay/order/types.ts deleted
1 -export type OrderVO = {  
2 - id: number  
3 - merchantId: number  
4 - appId: number  
5 - channelId: number  
6 - channelCode: string  
7 - merchantOrderId: string  
8 - subject: string  
9 - body: string  
10 - notifyUrl: string  
11 - notifyStatus: number  
12 - amount: number  
13 - channelFeeRate: number  
14 - channelFeeAmount: number  
15 - status: number  
16 - userIp: string  
17 - expireTime: string  
18 - successTime: string  
19 - notifyTime: string  
20 - successExtensionId: number  
21 - refundStatus: number  
22 - refundTimes: number  
23 - refundAmount: number  
24 - channelUserId: string  
25 - channelOrderNo: string  
26 -}  
yudao-ui-admin-vue3/src/api/pay/refund/index.ts
1 import request from '@/config/axios' 1 import request from '@/config/axios'
2 -import type { RefundVO } from './types' 2 +
  3 +export interface RefundVO {
  4 + id: number
  5 + merchantId: number
  6 + appId: number
  7 + channelId: number
  8 + channelCode: string
  9 + orderId: string
  10 + tradeNo: string
  11 + merchantOrderId: string
  12 + merchantRefundNo: string
  13 + notifyUrl: string
  14 + notifyStatus: number
  15 + status: number
  16 + type: number
  17 + payAmount: number
  18 + refundAmount: number
  19 + reason: string
  20 + userIp: string
  21 + channelOrderNo: string
  22 + channelRefundNo: string
  23 + channelErrorCode: string
  24 + channelErrorMsg: string
  25 + channelExtras: string
  26 + expireTime: Date
  27 + successTime: Date
  28 + notifyTime: Date
  29 + createTime: Date
  30 +}
  31 +
  32 +export interface RefundPageReqVO extends PageParam {
  33 + merchantId?: number
  34 + appId?: number
  35 + channelId?: number
  36 + channelCode?: string
  37 + orderId?: string
  38 + tradeNo?: string
  39 + merchantOrderId?: string
  40 + merchantRefundNo?: string
  41 + notifyUrl?: string
  42 + notifyStatus?: number
  43 + status?: number
  44 + type?: number
  45 + payAmount?: number
  46 + refundAmount?: number
  47 + reason?: string
  48 + userIp?: string
  49 + channelOrderNo?: string
  50 + channelRefundNo?: string
  51 + channelErrorCode?: string
  52 + channelErrorMsg?: string
  53 + channelExtras?: string
  54 + expireTime?: Date[]
  55 + successTime?: Date[]
  56 + notifyTime?: Date[]
  57 + createTime?: Date[]
  58 +}
  59 +
  60 +export interface PayRefundExportReqVO {
  61 + merchantId?: number
  62 + appId?: number
  63 + channelId?: number
  64 + channelCode?: string
  65 + orderId?: string
  66 + tradeNo?: string
  67 + merchantOrderId?: string
  68 + merchantRefundNo?: string
  69 + notifyUrl?: string
  70 + notifyStatus?: number
  71 + status?: number
  72 + type?: number
  73 + payAmount?: number
  74 + refundAmount?: number
  75 + reason?: string
  76 + userIp?: string
  77 + channelOrderNo?: string
  78 + channelRefundNo?: string
  79 + channelErrorCode?: string
  80 + channelErrorMsg?: string
  81 + channelExtras?: string
  82 + expireTime?: Date[]
  83 + successTime?: Date[]
  84 + notifyTime?: Date[]
  85 + createTime?: Date[]
  86 +}
3 87
4 // 查询列表退款订单 88 // 查询列表退款订单
5 -export const getRefundPageApi = (params) => { 89 +export const getRefundPageApi = (params: RefundPageReqVO) => {
6 return request.get({ url: '/pay/refund/page', params }) 90 return request.get({ url: '/pay/refund/page', params })
7 } 91 }
8 92
@@ -27,6 +111,6 @@ export const deleteRefundApi = (id: number) => { @@ -27,6 +111,6 @@ export const deleteRefundApi = (id: number) => {
27 } 111 }
28 112
29 // 导出退款订单 113 // 导出退款订单
30 -export const exportRefundApi = (params) => { 114 +export const exportRefundApi = (params: PayRefundExportReqVO) => {
31 return request.download({ url: '/pay/refund/export-excel', params }) 115 return request.download({ url: '/pay/refund/export-excel', params })
32 } 116 }
yudao-ui-admin-vue3/src/api/pay/refund/types.ts deleted
1 -export type RefundVO = {  
2 - id: number  
3 - merchantId: number  
4 - appId: number  
5 - channelId: number  
6 - channelCode: string  
7 - merchantOrderId: string  
8 - subject: string  
9 - body: string  
10 - notifyUrl: string  
11 - notifyStatus: number  
12 - amount: number  
13 - channelFeeRate: number  
14 - channelFeeAmount: number  
15 - status: number  
16 - userIp: string  
17 - expireTime: string  
18 - successTime: string  
19 - notifyTime: string  
20 - successExtensionId: number  
21 - refundStatus: number  
22 - refundTimes: number  
23 - refundAmount: number  
24 - channelUserId: string  
25 - channelOrderNo: string  
26 -}  
yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts
@@ -121,18 +121,8 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => { @@ -121,18 +121,8 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => {
121 if (schemaItem?.isSearch || schemaItem.search?.show) { 121 if (schemaItem?.isSearch || schemaItem.search?.show) {
122 let itemRenderName = schemaItem?.search?.itemRender?.name || '$input' 122 let itemRenderName = schemaItem?.search?.itemRender?.name || '$input'
123 const options: any[] = [] 123 const options: any[] = []
124 - let itemRender: FormItemRenderOptions  
125 - if (schemaItem.search?.itemRender) {  
126 - itemRender = schemaItem.search.itemRender  
127 - } else {  
128 - itemRender = {  
129 - name: itemRenderName,  
130 - props:  
131 - itemRenderName == '$input'  
132 - ? { placeholder: t('common.inputText') }  
133 - : { placeholder: t('common.selectText') }  
134 - }  
135 - } 124 + let itemRender: FormItemRenderOptions = {}
  125 +
136 if (schemaItem.dictType) { 126 if (schemaItem.dictType) {
137 const allOptions = { label: '全部', value: '' } 127 const allOptions = { label: '全部', value: '' }
138 options.push(allOptions) 128 options.push(allOptions)
@@ -146,8 +136,19 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => { @@ -146,8 +136,19 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => {
146 options: options, 136 options: options,
147 props: { placeholder: t('common.selectText') } 137 props: { placeholder: t('common.selectText') }
148 } 138 }
  139 + } else {
  140 + if (schemaItem.search?.itemRender) {
  141 + itemRender = schemaItem.search.itemRender
  142 + } else {
  143 + itemRender = {
  144 + name: itemRenderName,
  145 + props:
  146 + itemRenderName == '$input'
  147 + ? { placeholder: t('common.inputText') }
  148 + : { placeholder: t('common.selectText') }
  149 + }
  150 + }
149 } 151 }
150 -  
151 const searchSchemaItem = { 152 const searchSchemaItem = {
152 // 默认为 input 153 // 默认为 input
153 folding: searchSchema.length > spanLength - 1, 154 folding: searchSchema.length > spanLength - 1,
@@ -156,7 +157,6 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => { @@ -156,7 +157,6 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => {
156 title: schemaItem.search?.title || schemaItem.title, 157 title: schemaItem.search?.title || schemaItem.title,
157 span: span 158 span: span
158 } 159 }
159 -  
160 searchSchema.push(searchSchemaItem) 160 searchSchema.push(searchSchemaItem)
161 } 161 }
162 }) 162 })
yudao-ui-admin-vue3/src/views/pay/app/app.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
5 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 const { t } = useI18n() // 国际化 6 const { t } = useI18n() // 国际化
7 7
8 // 表单校验 8 // 表单校验
@@ -15,67 +15,61 @@ export const rules = reactive({ @@ -15,67 +15,61 @@ export const rules = reactive({
15 }) 15 })
16 16
17 // CrudSchema 17 // CrudSchema
18 -const crudSchemas = reactive<CrudSchema[]>([  
19 - {  
20 - label: t('common.index'),  
21 - field: 'id',  
22 - type: 'index',  
23 - form: {  
24 - show: false 18 +const crudSchemas = reactive<VxeCrudSchema>({
  19 + primaryKey: 'id',
  20 + primaryType: 'seq',
  21 + primaryTitle: '编号',
  22 + action: true,
  23 + columns: [
  24 + {
  25 + title: '应用名',
  26 + field: 'name',
  27 + isSearch: true
25 }, 28 },
26 - detail: {  
27 - show: false  
28 - }  
29 - },  
30 - {  
31 - label: '应用名',  
32 - field: 'name',  
33 - search: {  
34 - show: true  
35 - }  
36 - },  
37 - {  
38 - label: '商户名称',  
39 - field: 'payMerchant',  
40 - search: {  
41 - show: true  
42 - }  
43 - },  
44 - {  
45 - label: t('common.status'),  
46 - field: 'status',  
47 - dictType: DICT_TYPE.COMMON_STATUS,  
48 - dictClass: 'number',  
49 - search: {  
50 - show: true  
51 - }  
52 - },  
53 - {  
54 - label: t('common.createTime'),  
55 - field: 'createTime',  
56 - form: {  
57 - show: false 29 + {
  30 + title: '商户名称',
  31 + field: 'payMerchant',
  32 + isSearch: true
58 }, 33 },
59 - search: {  
60 - show: true,  
61 - component: 'DatePicker',  
62 - componentProps: {  
63 - type: 'datetimerange',  
64 - valueFormat: 'YYYY-MM-DD HH:mm:ss',  
65 - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]  
66 - }  
67 - }  
68 - },  
69 - {  
70 - label: t('table.action'),  
71 - field: 'action',  
72 - width: '240px',  
73 - form: {  
74 - show: false 34 + {
  35 + title: t('common.status'),
  36 + field: 'status',
  37 + dictType: DICT_TYPE.COMMON_STATUS,
  38 + dictClass: 'number',
  39 + isSearch: true
75 }, 40 },
76 - detail: {  
77 - show: false 41 + {
  42 + title: '支付结果的回调地址',
  43 + field: 'payNotifyUrl',
  44 + isSearch: true
  45 + },
  46 + {
  47 + title: '退款结果的回调地址',
  48 + field: 'refundNotifyUrl',
  49 + isSearch: true
  50 + },
  51 + {
  52 + title: '商户名称',
  53 + field: 'merchantName',
  54 + isSearch: true
  55 + },
  56 + {
  57 + title: '备注',
  58 + field: 'remark',
  59 + isTable: false,
  60 + isSearch: true
  61 + },
  62 + {
  63 + title: t('common.createTime'),
  64 + field: 'createTime',
  65 + isForm: false,
  66 + search: {
  67 + show: true,
  68 + itemRender: {
  69 + name: 'XDataTimePicker'
  70 + }
  71 + }
78 } 72 }
79 - }  
80 -])  
81 -export const { allSchemas } = useCrudSchemas(crudSchemas) 73 + ]
  74 +})
  75 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
yudao-ui-admin-vue3/src/views/pay/app/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:新增 -->
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['pay:app:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + <!-- 操作:导出 -->
  15 + <XButton
  16 + type="warning"
  17 + preIcon="ep:download"
  18 + :title="t('action.export')"
  19 + v-hasPermi="['pay:app:export']"
  20 + @click="handleExport()"
  21 + />
  22 + </template>
  23 + <template #actionbtns_default="{ row }">
  24 + <!-- 操作:修改 -->
  25 + <XTextButton
  26 + preIcon="ep:edit"
  27 + :title="t('action.edit')"
  28 + v-hasPermi="['pay:app:update']"
  29 + @click="handleUpdate(row.id)"
  30 + />
  31 + <!-- 操作:详情 -->
  32 + <XTextButton
  33 + preIcon="ep:view"
  34 + :title="t('action.detail')"
  35 + v-hasPermi="['pay:app:query']"
  36 + @click="handleDetail(row.id)"
  37 + />
  38 + <!-- 操作:删除 -->
  39 + <XTextButton
  40 + preIcon="ep:delete"
  41 + :title="t('action.del')"
  42 + v-hasPermi="['pay:app:delete']"
  43 + @click="handleDelete(row.id)"
  44 + />
  45 + </template>
  46 + </vxe-grid>
  47 + </ContentWrap>
  48 +
  49 + <XModal v-model="dialogVisible" :title="dialogTitle">
  50 + <!-- 对话框(添加 / 修改) -->
  51 + <Form
  52 + v-if="['create', 'update'].includes(actionType)"
  53 + :schema="allSchemas.formSchema"
  54 + :rules="rules"
  55 + ref="formRef"
  56 + />
  57 + <!-- 对话框(详情) -->
  58 + <Descriptions
  59 + v-if="actionType === 'detail'"
  60 + :schema="allSchemas.detailSchema"
  61 + :data="detailData"
  62 + />
  63 + <!-- 操作按钮 -->
  64 + <template #footer>
  65 + <!-- 按钮:保存 -->
  66 + <XButton
  67 + v-if="['create', 'update'].includes(actionType)"
  68 + type="primary"
  69 + :title="t('action.save')"
  70 + :loading="actionLoading"
  71 + @click="submitForm()"
  72 + />
  73 + <!-- 按钮:关闭 -->
  74 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  75 + </template>
  76 + </XModal>
  77 +</template>
1 <script setup lang="ts" name="App"> 78 <script setup lang="ts" name="App">
2 import { ref, unref } from 'vue' 79 import { ref, unref } from 'vue'
3 -import dayjs from 'dayjs'  
4 -import { ElMessage } from 'element-plus'  
5 -import { DICT_TYPE } from '@/utils/dict'  
6 -import { useTable } from '@/hooks/web/useTable'  
7 import { useI18n } from '@/hooks/web/useI18n' 80 import { useI18n } from '@/hooks/web/useI18n'
  81 +import { useMessage } from '@/hooks/web/useMessage'
  82 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  83 +import { VxeGridInstance } from 'vxe-table'
8 import { FormExpose } from '@/components/Form' 84 import { FormExpose } from '@/components/Form'
9 -import type { AppVO } from '@/api/pay/app/types'  
10 import { rules, allSchemas } from './app.data' 85 import { rules, allSchemas } from './app.data'
11 import * as AppApi from '@/api/pay/app' 86 import * as AppApi from '@/api/pay/app'
  87 +
12 const { t } = useI18n() // 国际化 88 const { t } = useI18n() // 国际化
  89 +const message = useMessage() // 消息弹窗
13 90
14 -// ========== 列表相关 ==========  
15 -const { register, tableObject, methods } = useTable<AppVO>({ 91 +// 列表相关的变量
  92 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  93 +const { gridOptions, getList, deleteData, exportList } = useVxeGrid<AppApi.AppVO>({
  94 + allSchemas: allSchemas,
16 getListApi: AppApi.getAppPageApi, 95 getListApi: AppApi.getAppPageApi,
17 - delListApi: AppApi.deleteAppApi, 96 + deleteApi: AppApi.deleteAppApi,
18 exportListApi: AppApi.exportAppApi 97 exportListApi: AppApi.exportAppApi
19 }) 98 })
20 -const { getList, setSearchParams, delList, exportList } = methods  
21 99
22 // ========== CRUD 相关 ========== 100 // ========== CRUD 相关 ==========
23 const actionLoading = ref(false) // 遮罩层 101 const actionLoading = ref(false) // 遮罩层
@@ -25,6 +103,7 @@ const actionType = ref(&#39;&#39;) // 操作按钮的类型 @@ -25,6 +103,7 @@ const actionType = ref(&#39;&#39;) // 操作按钮的类型
25 const dialogVisible = ref(false) // 是否显示弹出层 103 const dialogVisible = ref(false) // 是否显示弹出层
26 const dialogTitle = ref('edit') // 弹出层标题 104 const dialogTitle = ref('edit') // 弹出层标题
27 const formRef = ref<FormExpose>() // 表单 Ref 105 const formRef = ref<FormExpose>() // 表单 Ref
  106 +const detailData = ref() // 详情 Ref
28 107
29 // 设置标题 108 // 设置标题
30 const setDialogTile = (type: string) => { 109 const setDialogTile = (type: string) => {
@@ -38,14 +117,31 @@ const handleCreate = () =&gt; { @@ -38,14 +117,31 @@ const handleCreate = () =&gt; {
38 setDialogTile('create') 117 setDialogTile('create')
39 } 118 }
40 119
  120 +// 导出操作
  121 +const handleExport = async () => {
  122 + await exportList(xGrid, '应用信息.xls')
  123 +}
  124 +
41 // 修改操作 125 // 修改操作
42 -const handleUpdate = async (row: AppVO) => { 126 +const handleUpdate = async (rowId: number) => {
43 setDialogTile('update') 127 setDialogTile('update')
44 // 设置数据 128 // 设置数据
45 - const res = await AppApi.getAppApi(row.id) 129 + const res = await AppApi.getAppApi(rowId)
46 unref(formRef)?.setValues(res) 130 unref(formRef)?.setValues(res)
47 } 131 }
48 132
  133 +// 详情操作
  134 +const handleDetail = async (rowId: number) => {
  135 + setDialogTile('detail')
  136 + const res = await AppApi.getAppApi(rowId)
  137 + detailData.value = res
  138 +}
  139 +
  140 +// 删除操作
  141 +const handleDelete = async (rowId: number) => {
  142 + await deleteData(xGrid, rowId)
  143 +}
  144 +
49 // 提交按钮 145 // 提交按钮
50 const submitForm = async () => { 146 const submitForm = async () => {
51 const elForm = unref(formRef)?.getElFormRef() 147 const elForm = unref(formRef)?.getElFormRef()
@@ -55,132 +151,21 @@ const submitForm = async () =&gt; { @@ -55,132 +151,21 @@ const submitForm = async () =&gt; {
55 actionLoading.value = true 151 actionLoading.value = true
56 // 提交请求 152 // 提交请求
57 try { 153 try {
58 - const data = unref(formRef)?.formModel as AppVO 154 + const data = unref(formRef)?.formModel as AppApi.AppVO
59 if (actionType.value === 'create') { 155 if (actionType.value === 'create') {
60 await AppApi.createAppApi(data) 156 await AppApi.createAppApi(data)
61 - ElMessage.success(t('common.createSuccess')) 157 + message.success(t('common.createSuccess'))
62 } else { 158 } else {
63 await AppApi.updateAppApi(data) 159 await AppApi.updateAppApi(data)
64 - ElMessage.success(t('common.updateSuccess')) 160 + message.success(t('common.updateSuccess'))
65 } 161 }
66 - // 操作成功,重新加载列表  
67 dialogVisible.value = false 162 dialogVisible.value = false
68 - await getList()  
69 } finally { 163 } finally {
70 actionLoading.value = false 164 actionLoading.value = false
  165 + // 刷新列表
  166 + await getList(xGrid)
71 } 167 }
72 } 168 }
73 }) 169 })
74 } 170 }
75 -  
76 -// ========== 详情相关 ==========  
77 -const detailRef = ref() // 详情 Ref  
78 -  
79 -// 详情操作  
80 -const handleDetail = async (row: AppVO) => {  
81 - // 设置数据  
82 - detailRef.value = row  
83 - setDialogTile('detail')  
84 -}  
85 -  
86 -// ========== 初始化 ==========  
87 -getList()  
88 </script> 171 </script>
89 -  
90 -<template>  
91 - <!-- 搜索工作区 -->  
92 - <ContentWrap>  
93 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
94 - </ContentWrap>  
95 - <ContentWrap>  
96 - <!-- 操作工具栏 -->  
97 - <div class="mb-10px">  
98 - <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">  
99 - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}  
100 - </el-button>  
101 - <el-button  
102 - type="warning"  
103 - v-hasPermi="['system:post:export']"  
104 - :loading="tableObject.exportLoading"  
105 - @click="exportList('应用数据.xls')"  
106 - >  
107 - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}  
108 - </el-button>  
109 - </div>  
110 - <!-- 列表 -->  
111 - <Table  
112 - :columns="allSchemas.tableColumns"  
113 - :selection="false"  
114 - :data="tableObject.tableList"  
115 - :loading="tableObject.loading"  
116 - :pagination="{  
117 - total: tableObject.total  
118 - }"  
119 - v-model:pageSize="tableObject.pageSize"  
120 - v-model:currentPage="tableObject.currentPage"  
121 - @register="register"  
122 - >  
123 - <template #status="{ row }">  
124 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
125 - </template>  
126 - <template #createTime="{ row }">  
127 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
128 - </template>  
129 - <template #action="{ row }">  
130 - <el-button  
131 - link  
132 - type="primary"  
133 - v-hasPermi="['system:post:update']"  
134 - @click="handleUpdate(row)"  
135 - >  
136 - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}  
137 - </el-button>  
138 - <el-button  
139 - link  
140 - type="primary"  
141 - v-hasPermi="['system:post:update']"  
142 - @click="handleDetail(row)"  
143 - >  
144 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
145 - </el-button>  
146 - <el-button  
147 - link  
148 - type="primary"  
149 - v-hasPermi="['system:post:delete']"  
150 - @click="delList(row.id, false)"  
151 - >  
152 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}  
153 - </el-button>  
154 - </template>  
155 - </Table>  
156 - </ContentWrap>  
157 -  
158 - <XModal v-model="dialogVisible" :title="dialogTitle">  
159 - <!-- 对话框(添加 / 修改) -->  
160 - <Form  
161 - v-if="['create', 'update'].includes(actionType)"  
162 - :schema="allSchemas.formSchema"  
163 - :rules="rules"  
164 - ref="formRef"  
165 - />  
166 - <!-- 对话框(详情) -->  
167 - <Descriptions  
168 - v-if="actionType === 'detail'"  
169 - :schema="allSchemas.detailSchema"  
170 - :data="detailRef"  
171 - />  
172 - <!-- 操作按钮 -->  
173 - <template #footer>  
174 - <!-- 按钮:保存 -->  
175 - <XButton  
176 - v-if="['create', 'update'].includes(actionType)"  
177 - type="primary"  
178 - :title="t('action.save')"  
179 - :loading="actionLoading"  
180 - @click="submitForm()"  
181 - />  
182 - <!-- 按钮:关闭 -->  
183 - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />  
184 - </template>  
185 - </XModal>  
186 -</template>  
yudao-ui-admin-vue3/src/views/pay/merchant/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:新增 -->
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['pay:merchant:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + <!-- 操作:导出 -->
  15 + <XButton
  16 + type="warning"
  17 + preIcon="ep:download"
  18 + :title="t('action.export')"
  19 + v-hasPermi="['pay:merchant:export']"
  20 + @click="handleExport()"
  21 + />
  22 + </template>
  23 + <template #actionbtns_default="{ row }">
  24 + <!-- 操作:修改 -->
  25 + <XTextButton
  26 + preIcon="ep:edit"
  27 + :title="t('action.edit')"
  28 + v-hasPermi="['pay:merchant:update']"
  29 + @click="handleUpdate(row.id)"
  30 + />
  31 + <!-- 操作:详情 -->
  32 + <XTextButton
  33 + preIcon="ep:view"
  34 + :title="t('action.detail')"
  35 + v-hasPermi="['pay:merchant:query']"
  36 + @click="handleDetail(row.id)"
  37 + />
  38 + <!-- 操作:删除 -->
  39 + <XTextButton
  40 + preIcon="ep:delete"
  41 + :title="t('action.del')"
  42 + v-hasPermi="['pay:merchant:delete']"
  43 + @click="handleDelete(row.id)"
  44 + />
  45 + </template>
  46 + </vxe-grid>
  47 + </ContentWrap>
  48 + <XModal v-model="dialogVisible" :title="dialogTitle">
  49 + <!-- 对话框(添加 / 修改) -->
  50 + <Form
  51 + v-if="['create', 'update'].includes(actionType)"
  52 + :schema="allSchemas.formSchema"
  53 + :rules="rules"
  54 + ref="formRef"
  55 + />
  56 + <!-- 对话框(详情) -->
  57 + <Descriptions
  58 + v-if="actionType === 'detail'"
  59 + :schema="allSchemas.detailSchema"
  60 + :data="detailData"
  61 + />
  62 + <!-- 操作按钮 -->
  63 + <template #footer>
  64 + <!-- 按钮:保存 -->
  65 + <XButton
  66 + v-if="['create', 'update'].includes(actionType)"
  67 + type="primary"
  68 + :title="t('action.save')"
  69 + :loading="actionLoading"
  70 + @click="submitForm()"
  71 + />
  72 + <!-- 按钮:关闭 -->
  73 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  74 + </template>
  75 + </XModal>
  76 +</template>
1 <script setup lang="ts" name="Merchant"> 77 <script setup lang="ts" name="Merchant">
2 import { ref, unref } from 'vue' 78 import { ref, unref } from 'vue'
3 -import dayjs from 'dayjs'  
4 -import { ElMessage } from 'element-plus'  
5 -import { DICT_TYPE } from '@/utils/dict'  
6 -import { useTable } from '@/hooks/web/useTable'  
7 import { useI18n } from '@/hooks/web/useI18n' 79 import { useI18n } from '@/hooks/web/useI18n'
  80 +import { useMessage } from '@/hooks/web/useMessage'
  81 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  82 +import { VxeGridInstance } from 'vxe-table'
8 import { FormExpose } from '@/components/Form' 83 import { FormExpose } from '@/components/Form'
9 -import type { MerchantVO } from '@/api/pay/merchant/types'  
10 import { rules, allSchemas } from './merchant.data' 84 import { rules, allSchemas } from './merchant.data'
11 import * as MerchantApi from '@/api/pay/merchant' 85 import * as MerchantApi from '@/api/pay/merchant'
12 -const { t } = useI18n() // 国际化  
13 86
14 -// ========== 列表相关 ==========  
15 -const { register, tableObject, methods } = useTable<MerchantVO>({ 87 +const { t } = useI18n() // 国际化
  88 +const message = useMessage() // 消息弹窗
  89 +// 列表相关的变量
  90 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  91 +const { gridOptions, getList, deleteData, exportList } = useVxeGrid<MerchantApi.MerchantVO>({
  92 + allSchemas: allSchemas,
16 getListApi: MerchantApi.getMerchantPageApi, 93 getListApi: MerchantApi.getMerchantPageApi,
17 - delListApi: MerchantApi.deleteMerchantApi, 94 + deleteApi: MerchantApi.deleteMerchantApi,
18 exportListApi: MerchantApi.exportMerchantApi 95 exportListApi: MerchantApi.exportMerchantApi
19 }) 96 })
20 -const { getList, setSearchParams, delList, exportList } = methods  
21 97
22 // ========== CRUD 相关 ========== 98 // ========== CRUD 相关 ==========
23 const actionLoading = ref(false) // 遮罩层 99 const actionLoading = ref(false) // 遮罩层
@@ -25,6 +101,7 @@ const actionType = ref(&#39;&#39;) // 操作按钮的类型 @@ -25,6 +101,7 @@ const actionType = ref(&#39;&#39;) // 操作按钮的类型
25 const dialogVisible = ref(false) // 是否显示弹出层 101 const dialogVisible = ref(false) // 是否显示弹出层
26 const dialogTitle = ref('edit') // 弹出层标题 102 const dialogTitle = ref('edit') // 弹出层标题
27 const formRef = ref<FormExpose>() // 表单 Ref 103 const formRef = ref<FormExpose>() // 表单 Ref
  104 +const detailData = ref() // 详情 Ref
28 105
29 // 设置标题 106 // 设置标题
30 const setDialogTile = (type: string) => { 107 const setDialogTile = (type: string) => {
@@ -38,14 +115,31 @@ const handleCreate = () =&gt; { @@ -38,14 +115,31 @@ const handleCreate = () =&gt; {
38 setDialogTile('create') 115 setDialogTile('create')
39 } 116 }
40 117
  118 +// 导出操作
  119 +const handleExport = async () => {
  120 + await exportList(xGrid, '商户列表.xls')
  121 +}
  122 +
41 // 修改操作 123 // 修改操作
42 -const handleUpdate = async (row: MerchantVO) => { 124 +const handleUpdate = async (rowId: number) => {
43 setDialogTile('update') 125 setDialogTile('update')
44 // 设置数据 126 // 设置数据
45 - const res = await MerchantApi.getMerchantApi(row.id) 127 + const res = await MerchantApi.getMerchantApi(rowId)
46 unref(formRef)?.setValues(res) 128 unref(formRef)?.setValues(res)
47 } 129 }
48 130
  131 +// 详情操作
  132 +const handleDetail = async (rowId: number) => {
  133 + setDialogTile('detail')
  134 + const res = await MerchantApi.getMerchantApi(rowId)
  135 + detailData.value = res
  136 +}
  137 +
  138 +// 删除操作
  139 +const handleDelete = async (rowId: number) => {
  140 + await deleteData(xGrid, rowId)
  141 +}
  142 +
49 // 提交按钮 143 // 提交按钮
50 const submitForm = async () => { 144 const submitForm = async () => {
51 const elForm = unref(formRef)?.getElFormRef() 145 const elForm = unref(formRef)?.getElFormRef()
@@ -55,132 +149,21 @@ const submitForm = async () =&gt; { @@ -55,132 +149,21 @@ const submitForm = async () =&gt; {
55 actionLoading.value = true 149 actionLoading.value = true
56 // 提交请求 150 // 提交请求
57 try { 151 try {
58 - const data = unref(formRef)?.formModel as MerchantVO 152 + const data = unref(formRef)?.formModel as MerchantApi.MerchantVO
59 if (actionType.value === 'create') { 153 if (actionType.value === 'create') {
60 await MerchantApi.createMerchantApi(data) 154 await MerchantApi.createMerchantApi(data)
61 - ElMessage.success(t('common.createSuccess')) 155 + message.success(t('common.createSuccess'))
62 } else { 156 } else {
63 await MerchantApi.updateMerchantApi(data) 157 await MerchantApi.updateMerchantApi(data)
64 - ElMessage.success(t('common.updateSuccess')) 158 + message.success(t('common.updateSuccess'))
65 } 159 }
66 - // 操作成功,重新加载列表  
67 dialogVisible.value = false 160 dialogVisible.value = false
68 - await getList()  
69 } finally { 161 } finally {
70 actionLoading.value = false 162 actionLoading.value = false
  163 + // 刷新列表
  164 + await getList(xGrid)
71 } 165 }
72 } 166 }
73 }) 167 })
74 } 168 }
75 -  
76 -// ========== 详情相关 ==========  
77 -const detailRef = ref() // 详情 Ref  
78 -  
79 -// 详情操作  
80 -const handleDetail = async (row: MerchantVO) => {  
81 - // 设置数据  
82 - detailRef.value = row  
83 - setDialogTile('detail')  
84 -}  
85 -  
86 -// ========== 初始化 ==========  
87 -getList()  
88 </script> 169 </script>
89 -  
90 -<template>  
91 - <!-- 搜索工作区 -->  
92 - <ContentWrap>  
93 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
94 - </ContentWrap>  
95 - <ContentWrap>  
96 - <!-- 操作工具栏 -->  
97 - <div class="mb-10px">  
98 - <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">  
99 - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}  
100 - </el-button>  
101 - <el-button  
102 - type="warning"  
103 - v-hasPermi="['system:post:export']"  
104 - :loading="tableObject.exportLoading"  
105 - @click="exportList('商户数据.xls')"  
106 - >  
107 - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}  
108 - </el-button>  
109 - </div>  
110 - <!-- 列表 -->  
111 - <Table  
112 - :columns="allSchemas.tableColumns"  
113 - :selection="false"  
114 - :data="tableObject.tableList"  
115 - :loading="tableObject.loading"  
116 - :pagination="{  
117 - total: tableObject.total  
118 - }"  
119 - v-model:pageSize="tableObject.pageSize"  
120 - v-model:currentPage="tableObject.currentPage"  
121 - @register="register"  
122 - >  
123 - <template #status="{ row }">  
124 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
125 - </template>  
126 - <template #createTime="{ row }">  
127 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
128 - </template>  
129 - <template #action="{ row }">  
130 - <el-button  
131 - link  
132 - type="primary"  
133 - v-hasPermi="['system:post:update']"  
134 - @click="handleUpdate(row)"  
135 - >  
136 - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}  
137 - </el-button>  
138 - <el-button  
139 - link  
140 - type="primary"  
141 - v-hasPermi="['system:post:update']"  
142 - @click="handleDetail(row)"  
143 - >  
144 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
145 - </el-button>  
146 - <el-button  
147 - link  
148 - type="primary"  
149 - v-hasPermi="['system:post:delete']"  
150 - @click="delList(row.id, false)"  
151 - >  
152 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}  
153 - </el-button>  
154 - </template>  
155 - </Table>  
156 - </ContentWrap>  
157 -  
158 - <XModal v-model="dialogVisible" :title="dialogTitle">  
159 - <!-- 对话框(添加 / 修改) -->  
160 - <Form  
161 - v-if="['create', 'update'].includes(actionType)"  
162 - :schema="allSchemas.formSchema"  
163 - :rules="rules"  
164 - ref="formRef"  
165 - />  
166 - <!-- 对话框(详情) -->  
167 - <Descriptions  
168 - v-if="actionType === 'detail'"  
169 - :schema="allSchemas.detailSchema"  
170 - :data="detailRef"  
171 - />  
172 - <!-- 操作按钮 -->  
173 - <template #footer>  
174 - <!-- 按钮:保存 -->  
175 - <XButton  
176 - v-if="['create', 'update'].includes(actionType)"  
177 - type="primary"  
178 - :title="t('action.save')"  
179 - :loading="actionLoading"  
180 - @click="submitForm()"  
181 - />  
182 - <!-- 按钮:关闭 -->  
183 - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />  
184 - </template>  
185 - </XModal>  
186 -</template>  
yudao-ui-admin-vue3/src/views/pay/merchant/merchant.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
5 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 const { t } = useI18n() // 国际化 6 const { t } = useI18n() // 国际化
7 7
8 // 表单校验 8 // 表单校验
@@ -14,91 +14,61 @@ export const rules = reactive({ @@ -14,91 +14,61 @@ export const rules = reactive({
14 }) 14 })
15 15
16 // CrudSchema 16 // CrudSchema
17 -const crudSchemas = reactive<CrudSchema[]>([  
18 - {  
19 - label: t('common.index'),  
20 - field: 'id',  
21 - type: 'index',  
22 - form: {  
23 - show: false 17 +const crudSchemas = reactive<VxeCrudSchema>({
  18 + primaryKey: 'id',
  19 + primaryType: 'seq',
  20 + primaryTitle: '商户编号',
  21 + action: true,
  22 + columns: [
  23 + {
  24 + title: '商户号',
  25 + field: 'no',
  26 + isSearch: true
24 }, 27 },
25 - detail: {  
26 - show: false  
27 - }  
28 - },  
29 - {  
30 - label: '商户号',  
31 - field: 'no',  
32 - search: {  
33 - show: true  
34 - }  
35 - },  
36 - {  
37 - label: '商户全称',  
38 - field: 'code',  
39 - search: {  
40 - show: true  
41 - }  
42 - },  
43 - {  
44 - label: '商户简称',  
45 - field: 'shortName',  
46 - search: {  
47 - show: true  
48 - }  
49 - },  
50 - {  
51 - label: t('common.status'),  
52 - field: 'status',  
53 - dictType: DICT_TYPE.COMMON_STATUS,  
54 - dictClass: 'number',  
55 - search: {  
56 - show: true  
57 - }  
58 - },  
59 - {  
60 - label: t('form.remark'),  
61 - field: 'remark',  
62 - form: {  
63 - component: 'Input',  
64 - componentProps: {  
65 - type: 'textarea',  
66 - rows: 4  
67 - },  
68 - colProps: {  
69 - span: 24  
70 - } 28 + {
  29 + title: '商户全称',
  30 + field: 'code',
  31 + isSearch: true
71 }, 32 },
72 - table: {  
73 - show: false  
74 - }  
75 - },  
76 - {  
77 - label: t('common.createTime'),  
78 - field: 'createTime',  
79 - form: {  
80 - show: false 33 + {
  34 + title: '商户简称',
  35 + field: 'shortName',
  36 + isSearch: true
  37 + },
  38 + {
  39 + title: t('common.status'),
  40 + field: 'status',
  41 + dictType: DICT_TYPE.COMMON_STATUS,
  42 + dictClass: 'number',
  43 + isSearch: true
81 }, 44 },
82 - search: {  
83 - show: true,  
84 - component: 'DatePicker',  
85 - componentProps: {  
86 - type: 'datetimerange',  
87 - valueFormat: 'YYYY-MM-DD HH:mm:ss',  
88 - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] 45 + {
  46 + title: t('form.remark'),
  47 + field: 'remark',
  48 + isTable: false,
  49 + form: {
  50 + component: 'Input',
  51 + componentProps: {
  52 + type: 'textarea',
  53 + rows: 4
  54 + },
  55 + colProps: {
  56 + span: 24
  57 + }
89 } 58 }
90 - }  
91 - },  
92 - {  
93 - label: t('table.action'),  
94 - field: 'action',  
95 - width: '240px',  
96 - form: {  
97 - show: false  
98 }, 59 },
99 - detail: {  
100 - show: false 60 + {
  61 + title: t('common.createTime'),
  62 + field: 'createTime',
  63 + formatter: 'formatDate',
  64 + isForm: false,
  65 + search: {
  66 + show: true,
  67 + itemRender: {
  68 + name: 'XDataTimePicker'
  69 + }
  70 + }
101 } 71 }
102 - }  
103 -])  
104 -export const { allSchemas } = useCrudSchemas(crudSchemas) 72 + ]
  73 +})
  74 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
yudao-ui-admin-vue3/src/views/pay/order/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:新增 -->
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['pay:order:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + <!-- 操作:导出 -->
  15 + <XButton
  16 + type="warning"
  17 + preIcon="ep:download"
  18 + :title="t('action.export')"
  19 + v-hasPermi="['pay:order:export']"
  20 + @click="handleExport()"
  21 + />
  22 + </template>
  23 + <template #actionbtns_default="{ row }">
  24 + <!-- 操作:详情 -->
  25 + <XTextButton
  26 + preIcon="ep:view"
  27 + :title="t('action.detail')"
  28 + v-hasPermi="['pay:order:query']"
  29 + @click="handleDetail(row.id)"
  30 + />
  31 + </template>
  32 + </vxe-grid>
  33 + </ContentWrap>
  34 + <XModal v-model="dialogVisible" :title="dialogTitle">
  35 + <!-- 对话框(详情) -->
  36 + <Descriptions :schema="allSchemas.detailSchema" :data="detailData" />
  37 + <!-- 操作按钮 -->
  38 + <template #footer>
  39 + <!-- 按钮:关闭 -->
  40 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  41 + </template>
  42 + </XModal>
  43 +</template>
1 <script setup lang="ts" name="Order"> 44 <script setup lang="ts" name="Order">
2 -import { ref, unref } from 'vue'  
3 -import { ElMessage } from 'element-plus'  
4 -import { DICT_TYPE } from '@/utils/dict'  
5 -import { useTable } from '@/hooks/web/useTable' 45 +import { ref } from 'vue'
6 import { useI18n } from '@/hooks/web/useI18n' 46 import { useI18n } from '@/hooks/web/useI18n'
7 -import { FormExpose } from '@/components/Form'  
8 -import type { OrderVO } from '@/api/pay/order/types'  
9 -import { rules, allSchemas } from './order.data' 47 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  48 +import { VxeGridInstance } from 'vxe-table'
  49 +import { allSchemas } from './order.data'
10 import * as OrderApi from '@/api/pay/order' 50 import * as OrderApi from '@/api/pay/order'
  51 +
11 const { t } = useI18n() // 国际化 52 const { t } = useI18n() // 国际化
12 -// ========== 列表相关 ==========  
13 -const { register, tableObject, methods } = useTable<OrderVO>({ 53 +// 列表相关的变量
  54 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  55 +const { gridOptions, exportList } = useVxeGrid<OrderApi.OrderVO>({
  56 + allSchemas: allSchemas,
14 getListApi: OrderApi.getOrderPageApi, 57 getListApi: OrderApi.getOrderPageApi,
15 - delListApi: OrderApi.deleteOrderApi,  
16 exportListApi: OrderApi.exportOrderApi 58 exportListApi: OrderApi.exportOrderApi
17 }) 59 })
18 -const { getList, setSearchParams, delList, exportList } = methods  
19 // ========== CRUD 相关 ========== 60 // ========== CRUD 相关 ==========
20 const actionLoading = ref(false) // 遮罩层 61 const actionLoading = ref(false) // 遮罩层
21 const actionType = ref('') // 操作按钮的类型 62 const actionType = ref('') // 操作按钮的类型
22 const dialogVisible = ref(false) // 是否显示弹出层 63 const dialogVisible = ref(false) // 是否显示弹出层
23 const dialogTitle = ref('edit') // 弹出层标题 64 const dialogTitle = ref('edit') // 弹出层标题
24 -const formRef = ref<FormExpose>() // 表单 Ref  
25 - 65 +const detailData = ref() // 详情 Ref
26 // 设置标题 66 // 设置标题
27 const setDialogTile = (type: string) => { 67 const setDialogTile = (type: string) => {
28 dialogTitle.value = t('action.' + type) 68 dialogTitle.value = t('action.' + type)
@@ -34,137 +74,15 @@ const setDialogTile = (type: string) =&gt; { @@ -34,137 +74,15 @@ const setDialogTile = (type: string) =&gt; {
34 const handleCreate = () => { 74 const handleCreate = () => {
35 setDialogTile('create') 75 setDialogTile('create')
36 } 76 }
37 -  
38 -// 修改操作  
39 -const handleUpdate = async (row: OrderVO) => {  
40 - setDialogTile('update')  
41 - // 设置数据  
42 - const res = await OrderApi.getOrderApi(row.id)  
43 - unref(formRef)?.setValues(res)  
44 -}  
45 -  
46 -// 提交按钮  
47 -const submitForm = async () => {  
48 - const elForm = unref(formRef)?.getElFormRef()  
49 - if (!elForm) return  
50 - elForm.validate(async (valid) => {  
51 - if (valid) {  
52 - actionLoading.value = true  
53 - // 提交请求  
54 - try {  
55 - const data = unref(formRef)?.formModel as OrderVO  
56 - if (actionType.value === 'create') {  
57 - await OrderApi.createOrderApi(data)  
58 - ElMessage.success(t('common.createSuccess'))  
59 - } else {  
60 - await OrderApi.updateOrderApi(data)  
61 - ElMessage.success(t('common.updateSuccess'))  
62 - }  
63 - // 操作成功,重新加载列表  
64 - dialogVisible.value = false  
65 - await getList()  
66 - } finally {  
67 - actionLoading.value = false  
68 - }  
69 - }  
70 - }) 77 +// 导出操作
  78 +const handleExport = async () => {
  79 + await exportList(xGrid, '订单数据.xls')
71 } 80 }
72 81
73 -// ========== 详情相关 ==========  
74 -const detailRef = ref() // 详情 Ref  
75 -  
76 // 详情操作 82 // 详情操作
77 -const handleDetail = async (row: OrderVO) => { 83 +const handleDetail = async (rowId: number) => {
78 setDialogTile('detail') 84 setDialogTile('detail')
79 - // 设置数据  
80 - const res = await OrderApi.getOrderApi(row.id as number)  
81 - detailRef.value = res 85 + const res = await OrderApi.getOrderApi(rowId)
  86 + detailData.value = res
82 } 87 }
83 -  
84 -// ========== 初始化 ==========  
85 -getList()  
86 </script> 88 </script>
87 -<template>  
88 - <!-- 搜索工作区 -->  
89 - <ContentWrap>  
90 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
91 - </ContentWrap>  
92 - <ContentWrap>  
93 - <!-- 操作工具栏 -->  
94 - <div class="mb-10px">  
95 - <el-button type="primary" v-hasPermi="['pay:order:create']" @click="handleCreate">  
96 - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}  
97 - </el-button>  
98 - <el-button  
99 - type="warning"  
100 - v-hasPermi="['pay:order:export']"  
101 - :loading="tableObject.exportLoading"  
102 - @click="exportList('订单数据.xls')"  
103 - >  
104 - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}  
105 - </el-button>  
106 - </div>  
107 - <!-- 列表 -->  
108 - <Table  
109 - :columns="allSchemas.tableColumns"  
110 - :selection="false"  
111 - :data="tableObject.tableList"  
112 - :loading="tableObject.loading"  
113 - :pagination="{  
114 - total: tableObject.total  
115 - }"  
116 - v-model:pageSize="tableObject.pageSize"  
117 - v-model:currentPage="tableObject.currentPage"  
118 - @register="register"  
119 - >  
120 - <template #status="{ row }">  
121 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
122 - </template>  
123 - <template #action="{ row }">  
124 - <el-button link type="primary" v-hasPermi="['pay:order:update']" @click="handleUpdate(row)">  
125 - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}  
126 - </el-button>  
127 - <el-button link type="primary" v-hasPermi="['pay:order:update']" @click="handleDetail(row)">  
128 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
129 - </el-button>  
130 - <el-button  
131 - link  
132 - type="primary"  
133 - v-hasPermi="['pay:order:delete']"  
134 - @click="delList(row.id, false)"  
135 - >  
136 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}  
137 - </el-button>  
138 - </template>  
139 - </Table>  
140 - </ContentWrap>  
141 -  
142 - <XModal v-model="dialogVisible" :title="dialogTitle">  
143 - <!-- 对话框(添加 / 修改) -->  
144 - <Form  
145 - v-if="['create', 'update'].includes(actionType)"  
146 - :schema="allSchemas.formSchema"  
147 - :rules="rules"  
148 - ref="formRef"  
149 - />  
150 - <!-- 对话框(详情) -->  
151 - <Descriptions  
152 - v-if="actionType === 'detail'"  
153 - :schema="allSchemas.detailSchema"  
154 - :data="detailRef"  
155 - />  
156 - <!-- 操作按钮 -->  
157 - <template #footer>  
158 - <!-- 按钮:保存 -->  
159 - <XButton  
160 - v-if="['create', 'update'].includes(actionType)"  
161 - type="primary"  
162 - :title="t('action.save')"  
163 - :loading="actionLoading"  
164 - @click="submitForm()"  
165 - />  
166 - <!-- 按钮:关闭 -->  
167 - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />  
168 - </template>  
169 - </XModal>  
170 -</template>  
yudao-ui-admin-vue3/src/views/pay/order/order.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
5 import { DICT_TYPE } from '@/utils/dict' 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 const { t } = useI18n() // 国际化 6 const { t } = useI18n() // 国际化
7 7
8 // 表单校验 8 // 表单校验
@@ -23,166 +23,134 @@ export const rules = reactive({ @@ -23,166 +23,134 @@ export const rules = reactive({
23 refundAmount: [required] 23 refundAmount: [required]
24 }) 24 })
25 // CrudSchema 25 // CrudSchema
26 -const crudSchemas = reactive<CrudSchema[]>([  
27 - {  
28 - label: t('common.index'),  
29 - field: 'id',  
30 - type: 'index',  
31 - form: {  
32 - show: false  
33 - },  
34 - detail: {  
35 - show: false  
36 - }  
37 - },  
38 - {  
39 - label: '商户编号',  
40 - field: 'merchantId',  
41 - search: {  
42 - show: true  
43 - }  
44 - },  
45 - {  
46 - label: '应用编号',  
47 - field: 'appId',  
48 - search: {  
49 - show: true  
50 - }  
51 - },  
52 - {  
53 - label: '渠道编号',  
54 - field: 'channelId'  
55 - },  
56 - {  
57 - label: '渠道编码',  
58 - field: 'channelCode',  
59 - search: {  
60 - show: true  
61 - }  
62 - },  
63 - {  
64 - label: '渠道订单号',  
65 - field: 'merchantOrderId',  
66 - search: {  
67 - show: true  
68 - }  
69 - },  
70 - {  
71 - label: '商品标题',  
72 - field: 'subject'  
73 - },  
74 - {  
75 - label: '商品描述',  
76 - field: 'body'  
77 - },  
78 - {  
79 - label: '异步通知地址',  
80 - field: 'notifyUrl'  
81 - },  
82 - {  
83 - label: '回调商户状态',  
84 - field: 'notifyStatus',  
85 - dictType: DICT_TYPE.PAY_ORDER_NOTIFY_STATUS,  
86 - dictClass: 'number'  
87 - },  
88 - {  
89 - label: '支付金额',  
90 - field: 'amount',  
91 - search: {  
92 - show: true  
93 - }  
94 - },  
95 - {  
96 - label: '渠道手续费',  
97 - field: 'channelFeeRate',  
98 - search: {  
99 - show: true  
100 - }  
101 - },  
102 - {  
103 - label: '渠道手续金额',  
104 - field: 'channelFeeAmount',  
105 - search: {  
106 - show: true  
107 - }  
108 - },  
109 - {  
110 - label: '支付状态',  
111 - field: 'status',  
112 - dictType: DICT_TYPE.PAY_ORDER_STATUS,  
113 - dictClass: 'number',  
114 - search: {  
115 - show: true  
116 - }  
117 - },  
118 - {  
119 - label: '用户 IP',  
120 - field: 'userIp'  
121 - },  
122 - {  
123 - label: '订单失效时间',  
124 - field: 'expireTime'  
125 - },  
126 - {  
127 - label: '订单支付成功时间',  
128 - field: 'successTime'  
129 - },  
130 - {  
131 - label: '订单支付通知时间',  
132 - field: 'notifyTime'  
133 - },  
134 - {  
135 - label: '支付成功的订单拓展单编号',  
136 - field: 'successExtensionId'  
137 - },  
138 - {  
139 - label: '退款状态',  
140 - field: 'refundStatus',  
141 - dictType: DICT_TYPE.PAY_ORDER_REFUND_STATUS,  
142 - dictClass: 'number',  
143 - search: {  
144 - show: true  
145 - }  
146 - },  
147 - {  
148 - label: '退款次数',  
149 - field: 'refundTimes'  
150 - },  
151 - {  
152 - label: '退款总金额',  
153 - field: 'refundAmount'  
154 - },  
155 - {  
156 - label: '渠道用户编号',  
157 - field: 'channelUserId'  
158 - },  
159 - {  
160 - label: '渠道订单号',  
161 - field: 'channelOrderNo'  
162 - },  
163 - {  
164 - label: t('common.createTime'),  
165 - field: 'createTime',  
166 - form: {  
167 - show: false  
168 - },  
169 - search: {  
170 - show: true,  
171 - component: 'DatePicker',  
172 - componentProps: {  
173 - type: 'datetimerange',  
174 - valueFormat: 'YYYY-MM-DD HH:mm:ss',  
175 - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] 26 +const crudSchemas = reactive<VxeCrudSchema>({
  27 + primaryKey: 'id',
  28 + primaryType: 'seq',
  29 + primaryTitle: '岗位编号',
  30 + action: true,
  31 + columns: [
  32 + {
  33 + title: '商户编号',
  34 + field: 'merchantId',
  35 + isSearch: true
  36 + },
  37 + {
  38 + title: '应用编号',
  39 + field: 'appId',
  40 + isSearch: true
  41 + },
  42 + {
  43 + title: '渠道编号',
  44 + field: 'channelId'
  45 + },
  46 + {
  47 + title: '渠道编码',
  48 + field: 'channelCode',
  49 + isSearch: true
  50 + },
  51 + {
  52 + title: '渠道订单号',
  53 + field: 'merchantOrderId',
  54 + isSearch: true
  55 + },
  56 + {
  57 + title: '商品标题',
  58 + field: 'subject'
  59 + },
  60 + {
  61 + title: '商品描述',
  62 + field: 'body'
  63 + },
  64 + {
  65 + title: '异步通知地址',
  66 + field: 'notifyUrl'
  67 + },
  68 + {
  69 + title: '回调状态',
  70 + field: 'notifyStatus',
  71 + dictType: DICT_TYPE.PAY_ORDER_NOTIFY_STATUS,
  72 + dictClass: 'number'
  73 + },
  74 + {
  75 + title: '支付金额',
  76 + field: 'amount',
  77 + isSearch: true
  78 + },
  79 + {
  80 + title: '渠道手续费',
  81 + field: 'channelFeeRate',
  82 + isSearch: true
  83 + },
  84 + {
  85 + title: '渠道手续金额',
  86 + field: 'channelFeeAmount',
  87 + isSearch: true
  88 + },
  89 + {
  90 + title: '支付状态',
  91 + field: 'status',
  92 + dictType: DICT_TYPE.PAY_ORDER_STATUS,
  93 + dictClass: 'number',
  94 + isSearch: true
  95 + },
  96 + {
  97 + title: '用户 IP',
  98 + field: 'userIp'
  99 + },
  100 + {
  101 + title: '订单失效时间',
  102 + field: 'expireTime',
  103 + formatter: 'formatDate'
  104 + },
  105 + {
  106 + title: '支付时间',
  107 + field: 'successTime',
  108 + formatter: 'formatDate'
  109 + },
  110 + {
  111 + title: '支付通知时间',
  112 + field: 'notifyTime',
  113 + formatter: 'formatDate'
  114 + },
  115 + {
  116 + title: '拓展编号',
  117 + field: 'successExtensionId'
  118 + },
  119 + {
  120 + title: '退款状态',
  121 + field: 'refundStatus',
  122 + dictType: DICT_TYPE.PAY_ORDER_REFUND_STATUS,
  123 + dictClass: 'number',
  124 + isSearch: true
  125 + },
  126 + {
  127 + title: '退款次数',
  128 + field: 'refundTimes'
  129 + },
  130 + {
  131 + title: '退款总金额',
  132 + field: 'refundAmount'
  133 + },
  134 + {
  135 + title: '渠道用户编号',
  136 + field: 'channelUserId'
  137 + },
  138 + {
  139 + title: '渠道订单号',
  140 + field: 'channelOrderNo'
  141 + },
  142 + {
  143 + title: t('common.createTime'),
  144 + field: 'createTime',
  145 + formatter: 'formatDate',
  146 + isForm: false,
  147 + search: {
  148 + show: true,
  149 + itemRender: {
  150 + name: 'XDataTimePicker'
  151 + }
176 } 152 }
177 } 153 }
178 - },  
179 - {  
180 - label: t('table.action'),  
181 - field: 'action',  
182 - width: '270px',  
183 - form: {  
184 - show: false  
185 - }  
186 - }  
187 -])  
188 -export const { allSchemas } = useCrudSchemas(crudSchemas) 154 + ]
  155 +})
  156 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
yudao-ui-admin-vue3/src/views/pay/refund/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:导出 -->
  7 + <XButton
  8 + type="warning"
  9 + preIcon="ep:download"
  10 + :title="t('action.export')"
  11 + v-hasPermi="['pay:refund:export']"
  12 + @click="handleExport()"
  13 + />
  14 + </template>
  15 + <template #actionbtns_default="{ row }">
  16 + <!-- 操作:详情 -->
  17 + <XTextButton
  18 + preIcon="ep:view"
  19 + :title="t('action.detail')"
  20 + v-hasPermi="['pay:refund:query']"
  21 + @click="handleDetail(row.id)"
  22 + />
  23 + </template>
  24 + </vxe-grid>
  25 + </ContentWrap>
  26 +
  27 + <XModal v-model="dialogVisible" :title="t('action.detail')">
  28 + <!-- 对话框(详情) -->
  29 + <Descriptions :schema="allSchemas.detailSchema" :data="detailData" />
  30 + <!-- 操作按钮 -->
  31 + <template #footer>
  32 + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  33 + </template>
  34 + </XModal>
  35 +</template>
1 <script setup lang="ts" name="Refund"> 36 <script setup lang="ts" name="Refund">
2 import { ref } from 'vue' 37 import { ref } from 'vue'
3 -import dayjs from 'dayjs'  
4 -import { DICT_TYPE } from '@/utils/dict'  
5 -import { useTable } from '@/hooks/web/useTable'  
6 import { useI18n } from '@/hooks/web/useI18n' 38 import { useI18n } from '@/hooks/web/useI18n'
7 -import type { RefundVO } from '@/api/pay/refund/types' 39 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  40 +import { VxeGridInstance } from 'vxe-table'
8 import { allSchemas } from './refund.data' 41 import { allSchemas } from './refund.data'
9 import * as RefundApi from '@/api/pay/refund' 42 import * as RefundApi from '@/api/pay/refund'
  43 +
10 const { t } = useI18n() // 国际化 44 const { t } = useI18n() // 国际化
11 45
12 -// ========== 列表相关 ==========  
13 -const { register, tableObject, methods } = useTable<RefundVO>({ 46 +// 列表相关的变量
  47 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  48 +const { gridOptions, exportList } = useVxeGrid<RefundApi.RefundVO>({
  49 + allSchemas: allSchemas,
14 getListApi: RefundApi.getRefundPageApi, 50 getListApi: RefundApi.getRefundPageApi,
15 - delListApi: RefundApi.deleteRefundApi,  
16 exportListApi: RefundApi.exportRefundApi 51 exportListApi: RefundApi.exportRefundApi
17 }) 52 })
18 -const { getList, setSearchParams, delList, exportList } = methods 53 +
  54 +// 导出操作
  55 +const handleExport = async () => {
  56 + await exportList(xGrid, '退款订单.xls')
  57 +}
19 58
20 // ========== CRUD 相关 ========== 59 // ========== CRUD 相关 ==========
21 const dialogVisible = ref(false) // 是否显示弹出层 60 const dialogVisible = ref(false) // 是否显示弹出层
22 -const dialogTitle = ref('edit') // 弹出层标题  
23 -  
24 -// ========== 详情相关 ==========  
25 -const detailRef = ref() // 详情 Ref 61 +const detailData = ref() // 详情 Ref
26 62
27 // 详情操作 63 // 详情操作
28 -const handleDetail = async (row: RefundVO) => { 64 +const handleDetail = async (rowId: number) => {
29 // 设置数据 65 // 设置数据
30 - detailRef.value = RefundApi.getRefundApi(row.id)  
31 - dialogTitle.value = t('action.detail') 66 + detailData.value = RefundApi.getRefundApi(rowId)
32 dialogVisible.value = true 67 dialogVisible.value = true
33 } 68 }
34 -  
35 -// ========== 初始化 ==========  
36 -getList()  
37 </script> 69 </script>
38 -  
39 -<template>  
40 - <!-- 搜索工作区 -->  
41 - <ContentWrap>  
42 - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />  
43 - </ContentWrap>  
44 - <ContentWrap>  
45 - <!-- 操作工具栏 -->  
46 - <div class="mb-10px">  
47 - <el-button  
48 - type="warning"  
49 - v-hasPermi="['system:post:export']"  
50 - :loading="tableObject.exportLoading"  
51 - @click="exportList('退款订单.xls')"  
52 - >  
53 - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}  
54 - </el-button>  
55 - </div>  
56 - <!-- 列表 -->  
57 - <Table  
58 - :columns="allSchemas.tableColumns"  
59 - :selection="false"  
60 - :data="tableObject.tableList"  
61 - :loading="tableObject.loading"  
62 - :pagination="{  
63 - total: tableObject.total  
64 - }"  
65 - v-model:pageSize="tableObject.pageSize"  
66 - v-model:currentPage="tableObject.currentPage"  
67 - @register="register"  
68 - >  
69 - <template #status="{ row }">  
70 - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />  
71 - </template>  
72 - <template #createTime="{ row }">  
73 - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>  
74 - </template>  
75 - <template #action="{ row }">  
76 - <el-button  
77 - link  
78 - type="primary"  
79 - v-hasPermi="['system:post:update']"  
80 - @click="handleDetail(row)"  
81 - >  
82 - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}  
83 - </el-button>  
84 - <el-button  
85 - link  
86 - type="primary"  
87 - v-hasPermi="['system:post:delete']"  
88 - @click="delList(row.id, false)"  
89 - >  
90 - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}  
91 - </el-button>  
92 - </template>  
93 - </Table>  
94 - </ContentWrap>  
95 -  
96 - <XModal v-model="dialogVisible" :title="dialogTitle">  
97 - <!-- 对话框(详情) -->  
98 - <Descriptions :schema="allSchemas.detailSchema" :data="detailRef" />  
99 - <!-- 操作按钮 -->  
100 - <template #footer>  
101 - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>  
102 - </template>  
103 - </XModal>  
104 -</template>  
yudao-ui-admin-vue3/src/views/pay/refund/refund.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'  
4 import { DICT_TYPE } from '@/utils/dict' 3 import { DICT_TYPE } from '@/utils/dict'
  4 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
5 const { t } = useI18n() // 国际化 5 const { t } = useI18n() // 国际化
6 6
7 // CrudSchema 7 // CrudSchema
8 -const crudSchemas = reactive<CrudSchema[]>([  
9 - {  
10 - label: t('common.index'),  
11 - field: 'id',  
12 - type: 'index',  
13 - form: {  
14 - show: false  
15 - },  
16 - detail: {  
17 - show: false  
18 - }  
19 - },  
20 - {  
21 - label: '应用编号',  
22 - field: 'appId',  
23 - search: {  
24 - show: true  
25 - }  
26 - },  
27 - {  
28 - label: '商户名称',  
29 - field: 'merchantName'  
30 - },  
31 - {  
32 - label: '应用名称',  
33 - field: 'appName'  
34 - },  
35 - {  
36 - label: '商品名称',  
37 - field: 'subject'  
38 - },  
39 - {  
40 - label: '商户退款单号',  
41 - field: 'merchantRefundNo'  
42 - },  
43 - {  
44 - label: '商户订单号',  
45 - field: 'merchantOrderId'  
46 - },  
47 - {  
48 - label: '交易订单号',  
49 - field: 'tradeNo'  
50 - },  
51 - {  
52 - label: '支付金额',  
53 - field: 'payAmount'  
54 - },  
55 - {  
56 - label: '退款金额',  
57 - field: 'refundAmount'  
58 - },  
59 - {  
60 - label: '渠道编码',  
61 - field: 'channelCode',  
62 - search: {  
63 - show: true  
64 - }  
65 - },  
66 - {  
67 - label: '退款类型',  
68 - field: 'type',  
69 - dictType: DICT_TYPE.PAY_REFUND_ORDER_TYPE,  
70 - dictClass: 'number',  
71 - search: {  
72 - show: true  
73 - }  
74 - },  
75 - {  
76 - label: t('common.status'),  
77 - field: 'status',  
78 - dictType: DICT_TYPE.PAY_REFUND_ORDER_STATUS,  
79 - dictClass: 'number',  
80 - search: {  
81 - show: true  
82 - }  
83 - },  
84 - {  
85 - label: t('common.createTime'),  
86 - field: 'createTime',  
87 - form: {  
88 - show: false  
89 - },  
90 - search: {  
91 - show: true,  
92 - component: 'DatePicker',  
93 - componentProps: {  
94 - type: 'datetimerange',  
95 - valueFormat: 'YYYY-MM-DD HH:mm:ss',  
96 - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] 8 +const crudSchemas = reactive<VxeCrudSchema>({
  9 + primaryKey: 'id',
  10 + primaryType: 'seq',
  11 + primaryTitle: '序号',
  12 + action: true,
  13 + columns: [
  14 + {
  15 + title: '商户编号',
  16 + field: 'merchantId',
  17 + isSearch: true
  18 + },
  19 + {
  20 + title: '应用编号',
  21 + field: 'appId',
  22 + isSearch: true
  23 + },
  24 + {
  25 + title: '渠道编号',
  26 + field: 'channelId',
  27 + isSearch: true
  28 + },
  29 + {
  30 + title: '渠道编码',
  31 + field: 'channelCode',
  32 + dictType: DICT_TYPE.PAY_CHANNEL_CODE_TYPE,
  33 + dictClass: 'number',
  34 + isSearch: true
  35 + },
  36 + {
  37 + title: '支付订单编号',
  38 + field: 'orderId',
  39 + isSearch: true
  40 + },
  41 + {
  42 + title: '交易订单号',
  43 + field: 'tradeNo',
  44 + isSearch: true
  45 + },
  46 + {
  47 + title: '商户订单号',
  48 + field: 'merchantOrderId',
  49 + isSearch: true
  50 + },
  51 + {
  52 + title: '商户退款单号',
  53 + field: 'merchantRefundNo',
  54 + isSearch: true
  55 + },
  56 + {
  57 + title: '回调地址',
  58 + field: 'notifyUrl',
  59 + isSearch: true
  60 + },
  61 + {
  62 + title: '回调状态',
  63 + field: 'notifyStatus',
  64 + dictType: DICT_TYPE.PAY_ORDER_NOTIFY_STATUS,
  65 + dictClass: 'number',
  66 + isSearch: true
  67 + },
  68 + {
  69 + title: '退款类型',
  70 + field: 'type',
  71 + dictType: DICT_TYPE.PAY_REFUND_ORDER_TYPE,
  72 + dictClass: 'number',
  73 + isSearch: true
  74 + },
  75 + {
  76 + title: t('common.status'),
  77 + field: 'status',
  78 + dictType: DICT_TYPE.PAY_REFUND_ORDER_STATUS,
  79 + dictClass: 'number',
  80 + isSearch: true
  81 + },
  82 + {
  83 + title: '支付金额',
  84 + field: 'payAmount',
  85 + formatter: 'formatAmount',
  86 + isSearch: true
  87 + },
  88 + {
  89 + title: '退款金额',
  90 + field: 'refundAmount',
  91 + formatter: 'formatAmount',
  92 + isSearch: true
  93 + },
  94 + {
  95 + title: '退款原因',
  96 + field: 'reason',
  97 + isSearch: true
  98 + },
  99 + {
  100 + title: '用户IP',
  101 + field: 'userIp',
  102 + isSearch: true
  103 + },
  104 + {
  105 + title: '渠道订单号',
  106 + field: 'channelOrderNo',
  107 + isSearch: true
  108 + },
  109 + {
  110 + title: '渠道退款单号',
  111 + field: 'channelRefundNo',
  112 + isSearch: true
  113 + },
  114 + {
  115 + title: '渠道调用报错时',
  116 + field: 'channelErrorCode'
  117 + },
  118 + {
  119 + title: '渠道调用报错时',
  120 + field: 'channelErrorMsg'
  121 + },
  122 + {
  123 + title: '支付渠道的额外参数',
  124 + field: 'channelExtras'
  125 + },
  126 + {
  127 + title: '退款失效时间',
  128 + field: 'expireTime',
  129 + formatter: 'formatDate',
  130 + isForm: false,
  131 + search: {
  132 + show: true,
  133 + itemRender: {
  134 + name: 'XDataTimePicker'
  135 + }
  136 + }
  137 + },
  138 + {
  139 + title: '退款成功时间',
  140 + field: 'successTime',
  141 + formatter: 'formatDate',
  142 + isForm: false,
  143 + search: {
  144 + show: true,
  145 + itemRender: {
  146 + name: 'XDataTimePicker'
  147 + }
  148 + }
  149 + },
  150 + {
  151 + title: '退款通知时间',
  152 + field: 'notifyTime',
  153 + formatter: 'formatDate',
  154 + isForm: false,
  155 + search: {
  156 + show: true,
  157 + itemRender: {
  158 + name: 'XDataTimePicker'
  159 + }
  160 + }
  161 + },
  162 + {
  163 + title: t('common.createTime'),
  164 + field: 'createTime',
  165 + formatter: 'formatDate',
  166 + isForm: false,
  167 + search: {
  168 + show: true,
  169 + itemRender: {
  170 + name: 'XDataTimePicker'
  171 + }
97 } 172 }
98 } 173 }
99 - },  
100 - {  
101 - label: t('table.action'),  
102 - field: 'action',  
103 - width: '240px',  
104 - form: {  
105 - show: false  
106 - },  
107 - detail: {  
108 - show: false  
109 - }  
110 - }  
111 -])  
112 -export const { allSchemas } = useCrudSchemas(crudSchemas) 174 + ]
  175 +})
  176 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)