diff --git a/apps/web-antd/src/adapter/form.ts b/apps/web-antd/src/adapter/form.ts index d9edaf19c..93428bac5 100644 --- a/apps/web-antd/src/adapter/form.ts +++ b/apps/web-antd/src/adapter/form.ts @@ -8,6 +8,7 @@ import type { ComponentType } from './component'; import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; import { $t } from '@vben/locales'; +/** 手机号正则表达式(中国) */ const MOBILE_REGEX = /(?:0|86|\+86)?1[3-9]\d{9}/; async function initSetupVbenForm() { @@ -68,4 +69,3 @@ export { initSetupVbenForm, useVbenForm, z }; export type VbenFormSchema = FormSchema; export type { VbenFormProps }; -export type FormSchemaGetter = () => VbenFormSchema[]; diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index 9935d0b0c..c4dcb2a86 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -268,8 +268,8 @@ setupVbenVxeTable({ // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // vxeUI.formats.add // add by 星语:数量格式化,例如说:金额 - vxeUI.formats.add('formatAmount', { - cellFormatMethod({ cellValue }, digits = 2) { + vxeUI.formats.add('formatNumber', { + tableCellFormatMethod({ cellValue }, digits = 2) { if (cellValue === null || cellValue === undefined) { return ''; } @@ -283,6 +283,22 @@ setupVbenVxeTable({ return cellValue.toFixed(digits); }, }); + + vxeUI.formats.add('formatFraction', { + tableCellFormatMethod({ cellValue }) { + if (cellValue === null || cellValue === undefined) { + return '0.00'; + } + if (isString(cellValue)) { + cellValue = Number.parseFloat(cellValue); + } + // 如果非 number,则直接返回空串 + if (Number.isNaN(cellValue)) { + return '0.00'; + } + return `${(cellValue / 100).toFixed(2)}元`; + }, + }); }, useVbenForm, }); diff --git a/apps/web-antd/src/api/pay/app/index.ts b/apps/web-antd/src/api/pay/app/index.ts index 1eae34420..2b09c57d2 100644 --- a/apps/web-antd/src/api/pay/app/index.ts +++ b/apps/web-antd/src/api/pay/app/index.ts @@ -23,10 +23,21 @@ export namespace PayAppApi { id: number; status: number; } + + export interface AppPageReqVO extends PageParam { + name?: string; + status?: number; + remark?: string; + payNotifyUrl?: string; + refundNotifyUrl?: string; + transferNotifyUrl?: string; + merchantName?: string; + createTime?: Date[]; + } } /** 查询支付应用列表 */ -export function getAppPage(params: PageParam) { +export function getAppPage(params: PayAppApi.AppPageReqVO) { return requestClient.get>('/pay/app/page', { params, }); diff --git a/apps/web-antd/src/api/pay/demo/index.ts b/apps/web-antd/src/api/pay/demo/index.ts deleted file mode 100644 index a0f3c6886..000000000 --- a/apps/web-antd/src/api/pay/demo/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { PageParam, PageResult } from '@vben/request'; - -import { requestClient } from '#/api/request'; - -export namespace PayDemoApi { - /** 示例订单信息 */ - export interface DemoOrder { - spuId: number; - createTime: Date; - } -} - -/** 创建示例订单 */ -export function createDemoOrder(data: PayDemoApi.DemoOrder) { - return requestClient.post('/pay/demo-order/create', data); -} - -/** 获得示例订单 */ -export function getDemoOrder(id: number) { - return requestClient.get( - `/pay/demo-order/get?id=${id}`, - ); -} - -/** 获得示例订单分页 */ -export function getDemoOrderPage(params: PageParam) { - return requestClient.get>( - '/pay/demo-order/page', - { - params, - }, - ); -} - -/** 退款示例订单 */ -export function refundDemoOrder(id: number) { - return requestClient.put(`/pay/demo-order/refund?id=${id}`); -} diff --git a/apps/web-antd/src/api/pay/demo/order/index.ts b/apps/web-antd/src/api/pay/demo/order/index.ts new file mode 100644 index 000000000..262351059 --- /dev/null +++ b/apps/web-antd/src/api/pay/demo/order/index.ts @@ -0,0 +1,47 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace DemoOrderApi { + /** 示例订单信息 */ + export interface Order { + id?: number; + userId?: number; + spuName?: string; + price?: number; + payStatus?: boolean; + payOrderId?: number; + payTime?: Date; + payChannelCode?: string; + payRefundId?: number; + refundPrice?: number; + refundTime?: Date; + spuId?: number; + createTime?: Date; + } + + export interface OrderPageReqVO extends PageParam { + spuId?: number; + createTime?: Date[]; + } +} + +/** 创建示例订单 */ +export function createDemoOrder(data: DemoOrderApi.Order) { + return requestClient.post('/pay/demo-order/create', data); +} + +/** 获得示例订单分页 */ +export function getDemoOrderPage(params: DemoOrderApi.OrderPageReqVO) { + return requestClient.get>( + '/pay/demo-order/page', + { + params, + }, + ); +} + +/** 退款示例订单 */ +export function refundDemoOrder(id: number) { + return requestClient.put(`/pay/demo-order/refund?id=${id}`); +} diff --git a/apps/web-antd/src/api/pay/demo/transfer/index.ts b/apps/web-antd/src/api/pay/demo/transfer/index.ts deleted file mode 100644 index e06dbec8b..000000000 --- a/apps/web-antd/src/api/pay/demo/transfer/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { PageParam, PageResult } from '@vben/request'; - -import { requestClient } from '#/api/request'; - -export namespace PayDemoTransferApi { - /** 示例转账单信息 */ - export interface DemoTransfer { - price: number; - type: number; - userName: string; - alipayLogonId: string; - openid: string; - } -} - -/** 创建示例转账单 */ -export function createDemoTransfer(data: PayDemoTransferApi.DemoTransfer) { - return requestClient.post('/pay/demo-transfer/create', data); -} - -/** 获得示例转账单分页 */ -export function getDemoTransferPage(params: PageParam) { - return requestClient.get>( - '/pay/demo-transfer/page', - { - params, - }, - ); -} diff --git a/apps/web-antd/src/api/pay/demo/withdraw/index.ts b/apps/web-antd/src/api/pay/demo/withdraw/index.ts new file mode 100644 index 000000000..3711ff9e3 --- /dev/null +++ b/apps/web-antd/src/api/pay/demo/withdraw/index.ts @@ -0,0 +1,40 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace DemoWithdrawApi { + /** 示例提现单信息 */ + export interface Withdraw { + id?: number; + subject: string; + price: number; + userName: string; + userAccount: string; + type: number; + status?: number; + payTransferId?: number; + transferChannelCode?: string; + transferTime?: Date; + transferErrorMsg?: string; + } +} + +/** 查询示例提现单列表 */ +export function getDemoWithdrawPage(params: PageParam) { + return requestClient.get>( + '/pay/demo-withdraw/page', + { + params, + }, + ); +} + +/** 创建示例提现单 */ +export function createDemoWithdraw(data: DemoWithdrawApi.Withdraw) { + return requestClient.post('/pay/demo-withdraw/create', data); +} + +/** 发起提现单转账 */ +export function transferDemoWithdraw(id: number) { + return requestClient.post(`/pay/demo-withdraw/transfer?id=${id}`); +} diff --git a/apps/web-antd/src/api/pay/transfer/index.ts b/apps/web-antd/src/api/pay/transfer/index.ts index fd8bc9d3a..ba206ec5c 100644 --- a/apps/web-antd/src/api/pay/transfer/index.ts +++ b/apps/web-antd/src/api/pay/transfer/index.ts @@ -52,7 +52,9 @@ export function getTransfer(id: number) { ); } -/** 创建转账单 */ -export function createTransfer(data: PayTransferApi.Transfer) { - return requestClient.post('/pay/transfer/create', data); +/** 导出转账单 */ +export function exportTransfer(params: any) { + return requestClient.download('/pay/transfer/export-excel', { + params, + }); } diff --git a/apps/web-antd/src/components/upload/file-upload.vue b/apps/web-antd/src/components/upload/file-upload.vue index 5423ab9a3..7577eeea5 100644 --- a/apps/web-antd/src/components/upload/file-upload.vue +++ b/apps/web-antd/src/components/upload/file-upload.vue @@ -2,7 +2,7 @@ import type { UploadFile, UploadProps } from 'ant-design-vue'; import type { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface'; -import type { AxiosResponse } from '@vben/request'; +import type { FileUploadProps } from './typing'; import type { AxiosProgressEvent } from '#/api/infra/file'; @@ -20,44 +20,19 @@ import { useUpload, useUploadType } from './use-upload'; defineOptions({ name: 'FileUpload', inheritAttrs: false }); -const props = withDefaults( - defineProps<{ - // 根据后缀,或者其他 - accept?: string[]; - api?: ( - file: File, - onUploadProgress?: AxiosProgressEvent, - ) => Promise>; - // 上传的目录 - directory?: string; - disabled?: boolean; - helpText?: string; - // 最大数量的文件,Infinity不限制 - maxNumber?: number; - // 文件最大多少MB - maxSize?: number; - // 是否支持多选 - multiple?: boolean; - // support xxx.xxx.xx - resultField?: string; - // 是否显示下面的描述 - showDescription?: boolean; - value?: string | string[]; - }>(), - { - value: () => [], - directory: undefined, - disabled: false, - helpText: '', - maxSize: 2, - maxNumber: 1, - accept: () => [], - multiple: false, - api: undefined, - resultField: '', - showDescription: false, - }, -); +const props = withDefaults(defineProps(), { + value: () => [], + directory: undefined, + disabled: false, + helpText: '', + maxSize: 2, + maxNumber: 1, + accept: () => [], + multiple: false, + api: undefined, + resultField: '', + showDescription: false, +}); const emit = defineEmits(['change', 'update:value', 'delete', 'returnText']); const { accept, helpText, maxNumber, maxSize } = toRefs(props); const isInnerOperate = ref(false); @@ -112,7 +87,7 @@ watch( }, ); -const handleRemove = async (file: UploadFile) => { +async function handleRemove(file: UploadFile) { if (fileList.value) { const index = fileList.value.findIndex((item) => item.uid === file.uid); index !== -1 && fileList.value.splice(index, 1); @@ -122,9 +97,9 @@ const handleRemove = async (file: UploadFile) => { emit('change', value); emit('delete', file); } -}; +} -const beforeUpload = async (file: File) => { +async function beforeUpload(file: File) { // 使用现代的Blob.text()方法替代FileReader const fileContent = await file.text(); emit('returnText', fileContent); @@ -145,7 +120,7 @@ const beforeUpload = async (file: File) => { setTimeout(() => (isLtMsg.value = true), 1000); } return (isAct && !isLt) || Upload.LIST_IGNORE; -}; +} async function customRequest(info: UploadRequestOption) { let { api } = props; diff --git a/apps/web-antd/src/components/upload/helper.ts b/apps/web-antd/src/components/upload/helper.ts index a7a67639d..27313cea6 100644 --- a/apps/web-antd/src/components/upload/helper.ts +++ b/apps/web-antd/src/components/upload/helper.ts @@ -1,3 +1,8 @@ +/** + * 默认图片类型 + */ +export const defaultImageAccepts = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + export function checkFileType(file: File, accepts: string[]) { if (!accepts || accepts.length === 0) { return true; @@ -7,11 +12,6 @@ export function checkFileType(file: File, accepts: string[]) { return reg.test(file.name); } -/** - * 默认图片类型 - */ -export const defaultImageAccepts = ['jpg', 'jpeg', 'png', 'gif', 'webp']; - export function checkImgType( file: File, accepts: string[] = defaultImageAccepts, diff --git a/apps/web-antd/src/components/upload/image-upload.vue b/apps/web-antd/src/components/upload/image-upload.vue index 10da90861..392d47b9b 100644 --- a/apps/web-antd/src/components/upload/image-upload.vue +++ b/apps/web-antd/src/components/upload/image-upload.vue @@ -2,9 +2,7 @@ import type { UploadFile, UploadProps } from 'ant-design-vue'; import type { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface'; -import type { AxiosResponse } from '@vben/request'; - -import type { UploadListType } from './typing'; +import type { FileUploadProps } from './typing'; import type { AxiosProgressEvent } from '#/api/infra/file'; @@ -22,46 +20,20 @@ import { useUpload, useUploadType } from './use-upload'; defineOptions({ name: 'ImageUpload', inheritAttrs: false }); -const props = withDefaults( - defineProps<{ - // 根据后缀,或者其他 - accept?: string[]; - api?: ( - file: File, - onUploadProgress?: AxiosProgressEvent, - ) => Promise>; - // 上传的目录 - directory?: string; - disabled?: boolean; - helpText?: string; - listType?: UploadListType; - // 最大数量的文件,Infinity不限制 - maxNumber?: number; - // 文件最大多少MB - maxSize?: number; - // 是否支持多选 - multiple?: boolean; - // support xxx.xxx.xx - resultField?: string; - // 是否显示下面的描述 - showDescription?: boolean; - value?: string | string[]; - }>(), - { - value: () => [], - directory: undefined, - disabled: false, - listType: 'picture-card', - helpText: '', - maxSize: 2, - maxNumber: 1, - accept: () => defaultImageAccepts, - multiple: false, - api: undefined, - resultField: '', - showDescription: true, - }, -); +const props = withDefaults(defineProps(), { + value: () => [], + directory: undefined, + disabled: false, + listType: 'picture-card', + helpText: '', + maxSize: 2, + maxNumber: 1, + accept: () => defaultImageAccepts, + multiple: false, + api: undefined, + resultField: '', + showDescription: true, +}); const emit = defineEmits(['change', 'update:value', 'delete']); const { accept, helpText, maxNumber, maxSize } = toRefs(props); const isInnerOperate = ref(false); @@ -130,7 +102,7 @@ function getBase64(file: File) { }); } -const handlePreview = async (file: UploadFile) => { +async function handlePreview(file: UploadFile) { if (!file.url && !file.preview) { file.preview = await getBase64(file.originFileObj!); } @@ -141,9 +113,9 @@ const handlePreview = async (file: UploadFile) => { previewImage.value.slice( Math.max(0, previewImage.value.lastIndexOf('/') + 1), ); -}; +} -const handleRemove = async (file: UploadFile) => { +async function handleRemove(file: UploadFile) { if (fileList.value) { const index = fileList.value.findIndex((item) => item.uid === file.uid); index !== -1 && fileList.value.splice(index, 1); @@ -153,14 +125,14 @@ const handleRemove = async (file: UploadFile) => { emit('change', value); emit('delete', file); } -}; +} -const handleCancel = () => { +function handleCancel() { previewOpen.value = false; previewTitle.value = ''; -}; +} -const beforeUpload = async (file: File) => { +async function beforeUpload(file: File) { const { maxSize, accept } = props; const isAct = checkImgType(file, accept); if (!isAct) { @@ -177,7 +149,7 @@ const beforeUpload = async (file: File) => { setTimeout(() => (isLtMsg.value = true), 1000); } return (isAct && !isLt) || Upload.LIST_IGNORE; -}; +} async function customRequest(info: UploadRequestOption) { let { api } = props; diff --git a/apps/web-antd/src/components/upload/index.ts b/apps/web-antd/src/components/upload/index.ts index a66b2fca6..14e57fede 100644 --- a/apps/web-antd/src/components/upload/index.ts +++ b/apps/web-antd/src/components/upload/index.ts @@ -1,2 +1,3 @@ export { default as FileUpload } from './file-upload.vue'; export { default as ImageUpload } from './image-upload.vue'; +export { default as InputUpload } from './input-upload.vue'; diff --git a/apps/web-antd/src/components/upload/input-upload.vue b/apps/web-antd/src/components/upload/input-upload.vue new file mode 100644 index 000000000..11ee4cf03 --- /dev/null +++ b/apps/web-antd/src/components/upload/input-upload.vue @@ -0,0 +1,63 @@ + +