feat: 新增公司信息、大礼包订单和退款记录功能模块
添加公司信息管理页面,包含基本信息展示、人员管理、推广记录和收益明细功能
新增大礼包订单列表页面,支持订单查看和退款申请操作
实现退款申请记录功能,包含列表展示和详情查看
| | |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name": "公司信息", |
| | | "path": "/company-info", |
| | | "component": "./companyInfo" |
| | | }, |
| | | { |
| | | "name": "大礼包订单列表", |
| | | "path": "/bigGiftPackage", |
| | | "component": "./bigGiftPackage" |
| | | }, |
| | | { |
| | | "name": "退款申请记录", |
| | | "path": "/refundRecords", |
| | | "component": "./refundRecords/index" |
| | | }, |
| | | ]; |
| | |
| | | 'menu.order.bigGiftPackageOrder': '大礼包订单列表', |
| | | 'menu.order.physicalGoodsOrder': '实物商品订单', |
| | | 'menu.order.refundAudit': '退款申请审核', |
| | | 'menu.order.bigGiftPackageRefund': '大礼包订单退款', |
| | | 'menu.refundRecords': '退款申请记录', |
| | | 'menu.finance': '财务管理', |
| | | 'menu.finance.integralSettlement': '积分结算', |
| | | 'menu.finance.summaryStatistics': '汇总统计', |
| | | 'menu.companyInfo': '公司信息', |
| | | }; |
| New file |
| | |
| | | import { Modal, Form, Input, Upload, Button, Space, message } from 'antd'; |
| | | import { PlusOutlined } from '@ant-design/icons'; |
| | | import { useRef, useState } from 'react'; |
| | | import { customRequest } from '@/utils/utils'; |
| | | |
| | | const RefundApplyModal = ({ visible, onCancel, orderId, onSuccess }) => { |
| | | const [form] = Form.useForm(); |
| | | const [loading, setLoading] = useState(false); |
| | | const [fileList, setFileList] = useState([]); |
| | | const [previewImage, setPreviewImage] = useState(''); |
| | | const [previewVisible, setPreviewVisible] = useState(false); |
| | | |
| | | // 上传前验证 |
| | | const beforeUpload = (file) => { |
| | | const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg'; |
| | | if (!isJpgOrPng) { |
| | | message.error('只能上传 JPG/PNG 格式的图片!'); |
| | | return Upload.LIST_IGNORE; |
| | | } |
| | | const isLt5M = file.size / 1024 / 1024 < 5; |
| | | if (!isLt5M) { |
| | | message.error('图片大小不能超过 5MB!'); |
| | | return Upload.LIST_IGNORE; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | // 上传成功回调 |
| | | const handleUploadSuccess = (response) => { |
| | | const newFile = { |
| | | uid: response.name + Date.now(), |
| | | name: response.name || `图片${fileList.length + 1}`, |
| | | status: 'done', |
| | | url: IMAGE_URL + response, |
| | | response, |
| | | }; |
| | | setFileList([...fileList, newFile]); |
| | | }; |
| | | |
| | | // 删除图片 |
| | | const handleRemove = (file) => { |
| | | const newFileList = fileList.filter((item) => item.uid !== file.uid); |
| | | setFileList(newFileList); |
| | | }; |
| | | |
| | | // 预览图片 |
| | | const handlePreview = (file) => { |
| | | setPreviewImage(file.url || file.response); |
| | | setPreviewVisible(true); |
| | | }; |
| | | |
| | | const handleSubmit = async () => { |
| | | try { |
| | | const values = await form.validateFields(); |
| | | |
| | | // 如果没有上传图片,使用空字符串 |
| | | const voucherPicture = fileList.length > 0 |
| | | ? fileList.map(file => file.url || file.response).join(',') |
| | | : ''; |
| | | |
| | | setLoading(true); |
| | | |
| | | const res = await applyRefund({ |
| | | orderId, |
| | | refundReason: values.refundReason, |
| | | voucherPicture, |
| | | }); |
| | | |
| | | if (res?.code === 200) { |
| | | message.success('退款申请提交成功'); |
| | | form.resetFields(); |
| | | setFileList([]); |
| | | onCancel(); |
| | | onSuccess?.(); |
| | | } else { |
| | | message.error(res?.message || '退款申请提交失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('退款申请失败:', error); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | const uploadButton = ( |
| | | <div style={{ |
| | | display: 'flex', |
| | | flexDirection: 'column', |
| | | alignItems: 'center', |
| | | justifyContent: 'center', |
| | | height: '100%', |
| | | color: '#8c8c8c', |
| | | border: '1px dashed #d9d9d9', |
| | | borderRadius: 4, |
| | | backgroundColor: '#fafafa', |
| | | }}> |
| | | <PlusOutlined style={{ fontSize: 24, marginBottom: 8 }} /> |
| | | <div style={{ fontSize: 12 }}>上传图片</div> |
| | | </div> |
| | | ); |
| | | |
| | | return ( |
| | | <> |
| | | <Modal |
| | | title="申请退款" |
| | | open={visible} |
| | | onCancel={() => { |
| | | form.resetFields(); |
| | | setFileList([]); |
| | | onCancel(); |
| | | }} |
| | | footer={ |
| | | <Space> |
| | | <Button onClick={() => { |
| | | form.resetFields(); |
| | | setFileList([]); |
| | | onCancel(); |
| | | }}> |
| | | 取消 |
| | | </Button> |
| | | <Button |
| | | type="primary" |
| | | loading={loading} |
| | | onClick={handleSubmit} |
| | | > |
| | | 提交申请 |
| | | </Button> |
| | | </Space> |
| | | } |
| | | width={700} |
| | | > |
| | | <Form |
| | | form={form} |
| | | layout="vertical" |
| | | initialValues={{ |
| | | refundReason: '', |
| | | }} |
| | | > |
| | | <Form.Item |
| | | name="refundReason" |
| | | label="退款原因" |
| | | rules={[ |
| | | { required: true, message: '请输入退款原因' }, |
| | | { max: 500, message: '退款原因最多500字符' } |
| | | ]} |
| | | > |
| | | <Input.TextArea |
| | | rows={4} |
| | | placeholder="请详细描述退款原因..." |
| | | showCount |
| | | maxLength={500} |
| | | /> |
| | | </Form.Item> |
| | | |
| | | <Form.Item |
| | | name="voucherPicture" |
| | | label="凭证图片" |
| | | extra="支持上传图片作为退款凭证,可上传多张" |
| | | > |
| | | <Upload |
| | | action="/open/file/upload" |
| | | listType="picture-card" |
| | | fileList={fileList} |
| | | beforeUpload={beforeUpload} |
| | | customRequest={(params) => customRequest(params, 2)} |
| | | onSuccess={handleUploadSuccess} |
| | | onRemove={handleRemove} |
| | | onPreview={handlePreview} |
| | | accept="image/*" |
| | | > |
| | | {fileList.length >= 5 ? null : uploadButton} |
| | | </Upload> |
| | | </Form.Item> |
| | | </Form> |
| | | </Modal> |
| | | |
| | | {/* 图片预览 */} |
| | | {previewVisible && ( |
| | | <Modal |
| | | open={previewVisible} |
| | | footer={null} |
| | | onCancel={() => setPreviewVisible(false)} |
| | | width={600} |
| | | > |
| | | <img |
| | | alt="预览图片" |
| | | style={{ width: '100%' }} |
| | | src={previewImage} |
| | | /> |
| | | </Modal> |
| | | )} |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default RefundApplyModal; |
| New file |
| | |
| | | import { ProTable, Modal, message } from '@ant-design/pro-components'; |
| | | import { useRef, useState } from 'react'; |
| | | import { Button, Space } from 'antd'; |
| | | import { getRefundOrderList } from './service'; |
| | | import OrderDetailModal from '../order/bigGiftPackageOrder/components/OrderDetailModal'; |
| | | import RefundApplyModal from './components/RefundApplyModal'; |
| | | import { buildProTableDataSource } from '@/utils/antdUtils'; |
| | | |
| | | const BigGiftPackageRefundOrder = () => { |
| | | const actionRef = useRef(); |
| | | const [detailVisible, setDetailVisible] = useState(false); |
| | | const [refundVisible, setRefundVisible] = useState(false); |
| | | const [currentOrderId, setCurrentOrderId] = useState(null); |
| | | |
| | | // 支付类型映射 |
| | | const paymentTypeMap = { |
| | | 1: '订金+尾款', |
| | | 2: '全款', |
| | | }; |
| | | |
| | | // 订单状态映射 |
| | | const statusMap = { |
| | | 1: { text: '待付款', color: '#faad14' }, |
| | | 2: { text: '已付订金', color: '' }, |
| | | 3: { text: '完成支付', color: '#52c41a' }, |
| | | 4: { text: '确认收货', color: '#1890ff' }, |
| | | 5: { text: '已退款', color: '#722ed1' }, |
| | | }; |
| | | |
| | | const handleDetail = (id) => { |
| | | setCurrentOrderId(id); |
| | | setDetailVisible(true); |
| | | }; |
| | | |
| | | const handleRefund = (id) => { |
| | | setCurrentOrderId(id); |
| | | setRefundVisible(true); |
| | | }; |
| | | |
| | | const columns = [ |
| | | { |
| | | title: '序号', |
| | | dataIndex: 'index', |
| | | hideInSearch: true, |
| | | align: 'center', |
| | | width: 60, |
| | | render: (text, record, index) => index + 1, |
| | | }, |
| | | { |
| | | title: '所属公司', |
| | | dataIndex: 'companyName', |
| | | width: 150, |
| | | ellipsis: true, |
| | | search: false, |
| | | }, |
| | | { |
| | | title: '订单编号', |
| | | dataIndex: 'code', |
| | | width: 180, |
| | | ellipsis: true, |
| | | }, |
| | | { |
| | | title: '下单时间', |
| | | dataIndex: 'createTime', |
| | | valueType: 'dateRange', |
| | | width: 200, |
| | | search: { |
| | | transform: (value) => { |
| | | return { |
| | | time: value ? value.join(' - ') : undefined, |
| | | }; |
| | | }, |
| | | }, |
| | | render: (_, record) => record.createTime || '-', |
| | | }, |
| | | { |
| | | title: '下单用户', |
| | | dataIndex: 'userName', |
| | | width: 120, |
| | | ellipsis: true, |
| | | search: false, |
| | | }, |
| | | { |
| | | title: '用户手机号', |
| | | dataIndex: 'phone', |
| | | width: 130, |
| | | ellipsis: true, |
| | | }, |
| | | { |
| | | title: '订单价格', |
| | | dataIndex: 'orderPrice', |
| | | width: 120, |
| | | hideInSearch: true, |
| | | render: (text) => `¥${text || 0}`, |
| | | }, |
| | | { |
| | | title: '商品名称', |
| | | dataIndex: 'bigGiftPackageName', |
| | | width: 200, |
| | | ellipsis: true, |
| | | hideInSearch: true, |
| | | }, |
| | | { |
| | | title: '支付方式', |
| | | dataIndex: 'paymentType', |
| | | width: 120, |
| | | hideInSearch: true, |
| | | render: (text) => paymentTypeMap[text] || '-', |
| | | }, |
| | | { |
| | | title: '定金', |
| | | dataIndex: 'deposit', |
| | | width: 100, |
| | | hideInSearch: true, |
| | | render: (text) => `¥${text || 0}`, |
| | | }, |
| | | { |
| | | title: '尾款', |
| | | dataIndex: 'finalPayment', |
| | | width: 100, |
| | | hideInSearch: true, |
| | | render: (text) => `¥${text || 0}`, |
| | | }, |
| | | { |
| | | title: '订单状态', |
| | | dataIndex: 'status', |
| | | valueType: 'select', |
| | | width: 120, |
| | | valueEnum: { |
| | | 1: { text: '待付款' }, |
| | | 2: { text: '已付订金' }, |
| | | 3: { text: '完成支付' }, |
| | | 4: { text: '确认收货' }, |
| | | 5: { text: '已退款' }, |
| | | }, |
| | | render: (status, record) => { |
| | | const statusInfo = statusMap[record.status] || { text: '未知', color: '#d9d9d9' }; |
| | | return ( |
| | | <span style={{ |
| | | color: statusInfo.color, |
| | | fontWeight: 500 |
| | | }}> |
| | | {statusInfo.text} |
| | | </span> |
| | | ); |
| | | }, |
| | | }, |
| | | { |
| | | title: '操作', |
| | | dataIndex: 'action', |
| | | width: 180, |
| | | hideInSearch: true, |
| | | render: (_, record) => ( |
| | | <Space> |
| | | <Button |
| | | type="link" |
| | | size="small" |
| | | onClick={() => handleDetail(record.id)} |
| | | > |
| | | 详情 |
| | | </Button> |
| | | |
| | | {/* 只有已支付、已付订金、确认收货状态的订单可以申请退款 */} |
| | | {record.status !== 1 && record.status !== 5 && ( |
| | | <Button |
| | | type="link" |
| | | size="small" |
| | | onClick={() => handleRefund(record.id)} |
| | | > |
| | | 申请退款 |
| | | </Button> |
| | | )} |
| | | </Space> |
| | | ), |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <div> |
| | | <ProTable |
| | | actionRef={actionRef} |
| | | rowKey="id" |
| | | cardBordered |
| | | search={{ |
| | | labelWidth: 'auto', |
| | | defaultCollapsed: false, |
| | | }} |
| | | request={(params) => buildProTableDataSource(getRefundOrderList, params)} |
| | | columns={columns} |
| | | pagination={{ |
| | | defaultPageSize: 10, |
| | | showQuickJumper: true, |
| | | showSizeChanger: true, |
| | | }} |
| | | scroll={{ x: 1600 }} |
| | | /> |
| | | |
| | | {/* 订单详情弹窗 */} |
| | | <OrderDetailModal |
| | | visible={detailVisible} |
| | | onCancel={() => setDetailVisible(false)} |
| | | orderId={currentOrderId} |
| | | /> |
| | | |
| | | {/* 退款申请弹窗 */} |
| | | <RefundApplyModal |
| | | visible={refundVisible} |
| | | onCancel={() => setRefundVisible(false)} |
| | | orderId={currentOrderId} |
| | | onSuccess={() => { |
| | | // 刷新列表 |
| | | actionRef.current?.reload(); |
| | | message.success('退款申请已提交'); |
| | | }} |
| | | /> |
| | | </div> |
| | | ); |
| | | }; |
| | | |
| | | export default BigGiftPackageRefundOrder; |
| New file |
| | |
| | | import { request } from '@umijs/max'; |
| | | |
| | | // 获取大礼包订单列表 |
| | | export const getRefundOrderList = async (data) => { |
| | | return request('/agent/t-big-gift-package-order/pageList', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // 获取订单详情 |
| | | export const getOrderDetail = async (id) => { |
| | | return request(`/agent/t-big-gift-package-order/detail/${id}`, { |
| | | method: 'GET', |
| | | }); |
| | | }; |
| | | |
| | | // 申请退款 |
| | | export const applyRefund = async (data) => { |
| | | return request('/agent/t-big-gift-package-order/applyRefund', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | }; |
| New file |
| | |
| | | import { ProTable } from '@ant-design/pro-components'; |
| | | import { useRef, useState } from 'react'; |
| | | import { getProfitPageList } from '../service'; |
| | | import OrderDetailModal from '@/pages/order/bigGiftPackageOrder/components/OrderDetailModal'; |
| | | import { buildProTableDataSource } from '@/utils/antdUtils'; |
| | | |
| | | const CompanyProfitDetail = ({ companyId }) => { |
| | | const actionRef = useRef(); |
| | | const [orderDetailVisible, setOrderDetailVisible] = useState(false); |
| | | const [currentOrderId, setCurrentOrderId] = useState(null); |
| | | |
| | | const showOrderDetail = (id) => { |
| | | setCurrentOrderId(id); |
| | | setOrderDetailVisible(true); |
| | | }; |
| | | |
| | | const columns = [ |
| | | { |
| | | title: '序号', |
| | | dataIndex: 'index', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (_, __, index) => index + 1, |
| | | }, |
| | | { |
| | | title: '订单编号', |
| | | dataIndex: 'code', |
| | | align: 'center', |
| | | }, |
| | | { |
| | | title: '下单时间', |
| | | dataIndex: 'createTime', |
| | | align: 'center', |
| | | valueType: 'dateRange', |
| | | hideInTable: true, |
| | | fieldProps: { |
| | | placeholder: ['开始时间', '结束时间'], |
| | | format: 'YYYY-MM-DD', |
| | | }, |
| | | }, |
| | | { |
| | | title: '下单用户', |
| | | dataIndex: 'userName', |
| | | align: 'center', |
| | | fieldProps: { |
| | | placeholder: '请输入用户姓名', |
| | | }, |
| | | }, |
| | | { |
| | | title: '用户手机号', |
| | | dataIndex: 'phone', |
| | | align: 'center', |
| | | fieldProps: { |
| | | placeholder: '请输入用户手机号', |
| | | }, |
| | | }, |
| | | { |
| | | title: '订单价格', |
| | | dataIndex: 'orderPrice', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (orderPrice) => ( |
| | | <span>{orderPrice ? Number(orderPrice).toFixed(2) : '0.00'}</span> |
| | | ), |
| | | }, |
| | | { |
| | | title: '本人收益金额', |
| | | dataIndex: 'saleProfit', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (saleProfit) => ( |
| | | <span style={{ color: '#52c41a', fontWeight: 'bold' }}> |
| | | {saleProfit ? Number(saleProfit).toFixed(2) : '0.00'} |
| | | </span> |
| | | ), |
| | | }, |
| | | { |
| | | title: '操作', |
| | | dataIndex: 'action', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (_, record) => ( |
| | | <a |
| | | onClick={() => showOrderDetail(record.id)} |
| | | style={{ color: '#1890ff' }} |
| | | > |
| | | 详情 |
| | | </a> |
| | | ), |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <> |
| | | <ProTable |
| | | rowKey="id" |
| | | columns={columns} |
| | | actionRef={actionRef} |
| | | cardBordered |
| | | request={async (params) => buildProTableDataSource(getProfitPageList, { companyId, ...params })} |
| | | search={{ |
| | | labelWidth: 'auto', |
| | | defaultCollapsed: false, |
| | | }} |
| | | pagination={{ |
| | | defaultPageSize: 10, |
| | | showQuickJumper: true, |
| | | }} |
| | | /> |
| | | |
| | | <OrderDetailModal |
| | | visible={orderDetailVisible} |
| | | onCancel={() => setOrderDetailVisible(false)} |
| | | orderId={currentOrderId} |
| | | /> |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default CompanyProfitDetail; |
| New file |
| | |
| | | import { ProTable } from '@ant-design/pro-components'; |
| | | import { useRef } from 'react'; |
| | | import { getPromotionPageList } from '../service'; |
| | | import { Tag } from 'antd'; |
| | | import { buildProTableDataSource } from '@/utils/antdUtils'; |
| | | |
| | | const CompanyPromotionRecord = ({ companyId }) => { |
| | | const actionRef = useRef(); |
| | | |
| | | const columns = [ |
| | | { |
| | | title: '上级用户', |
| | | dataIndex: 'lastUserName', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | }, |
| | | { |
| | | title: '上级用户电话', |
| | | dataIndex: 'lastPhone', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | }, |
| | | { |
| | | title: '上级用户角色', |
| | | dataIndex: 'lastRoleName', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (lastRoleName) => { |
| | | const roleMap = { |
| | | 1: { text: '游客', color: 'default' }, |
| | | 2: { text: '营销员', color: 'blue' }, |
| | | 3: { text: '合伙人', color: 'green' }, |
| | | }; |
| | | const role = roleMap[lastRoleName] || { text: '未知', color: 'default' }; |
| | | return <Tag color={role.color}>{role.text}</Tag>; |
| | | }, |
| | | }, |
| | | { |
| | | title: '上级用户', |
| | | dataIndex: 'lastUserName', |
| | | align: 'center', |
| | | hideInTable: true, |
| | | fieldProps: { |
| | | placeholder: '请输入上级用户姓名', |
| | | }, |
| | | }, |
| | | { |
| | | title: '上级手机号', |
| | | dataIndex: 'lastPhone', |
| | | align: 'center', |
| | | hideInTable: true, |
| | | fieldProps: { |
| | | placeholder: '请输入上级用户电话', |
| | | }, |
| | | }, |
| | | { |
| | | title: '头像', |
| | | dataIndex: 'lastAvatar', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | hideInTable: true, |
| | | render: (_, record) => ( |
| | | record.lastAvatar ? ( |
| | | <img |
| | | src={record.lastAvatar} |
| | | alt="头像" |
| | | style={{ width: 32, height: 32, borderRadius: '50%' }} |
| | | /> |
| | | ) : ( |
| | | <span>-</span> |
| | | ) |
| | | ), |
| | | }, |
| | | { |
| | | title: '用户名', |
| | | dataIndex: 'userName', |
| | | align: 'center', |
| | | fieldProps: { |
| | | placeholder: '请输入用户名', |
| | | }, |
| | | }, |
| | | { |
| | | title: '联系电话', |
| | | dataIndex: 'phone', |
| | | align: 'center', |
| | | fieldProps: { |
| | | placeholder: '请输入联系电话', |
| | | }, |
| | | }, |
| | | { |
| | | title: '当前角色', |
| | | dataIndex: 'roleName', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (roleName) => { |
| | | const roleMap = { |
| | | 1: '游客', |
| | | 2: '营销员', |
| | | 3: '合伙人', |
| | | }; |
| | | return roleMap[roleName] || '未知'; |
| | | }, |
| | | }, |
| | | { |
| | | title: '状态', |
| | | dataIndex: 'status', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (status) => { |
| | | const statusMap = { |
| | | 1: { text: '正常', color: 'green' }, |
| | | 2: { text: '冻结', color: 'red' }, |
| | | }; |
| | | const statusInfo = statusMap[status] || { text: '未知', color: 'default' }; |
| | | return <Tag color={statusInfo.color}>{statusInfo.text}</Tag>; |
| | | }, |
| | | }, |
| | | { |
| | | title: '合计消费', |
| | | dataIndex: 'totalConsume', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (totalConsume) => ( |
| | | <span>{totalConsume ? Number(totalConsume).toFixed(2) : '0.00'}</span> |
| | | ), |
| | | }, |
| | | { |
| | | title: '合计收益', |
| | | dataIndex: 'totalIncome', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (totalIncome) => ( |
| | | <span>{totalIncome ? Number(totalIncome).toFixed(2) : '0.00'}</span> |
| | | ), |
| | | }, |
| | | { |
| | | title: '已结算收益', |
| | | dataIndex: 'totalSettledIncome', |
| | | align: 'center', |
| | | hideInSearch: true, |
| | | render: (totalSettledIncome) => ( |
| | | <span>{totalSettledIncome ? Number(totalSettledIncome).toFixed(2) : '0.00'}</span> |
| | | ), |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <ProTable |
| | | rowKey="userId" |
| | | columns={columns} |
| | | actionRef={actionRef} |
| | | cardBordered |
| | | request={async (params) => buildProTableDataSource(getPromotionPageList, { companyId, ...params })} |
| | | search={{ |
| | | labelWidth: 'auto', |
| | | defaultCollapsed: false, |
| | | }} |
| | | pagination={{ |
| | | defaultPageSize: 10, |
| | | showQuickJumper: true, |
| | | }} |
| | | /> |
| | | ); |
| | | }; |
| | | |
| | | export default CompanyPromotionRecord; |
| New file |
| | |
| | | import { Button, Modal, Space, Typography } from 'antd'; |
| | | import { forwardRef, useImperativeHandle, useState } from 'react'; |
| | | import { DownloadOutlined } from '@ant-design/icons'; |
| | | import { request } from '@umijs/max'; |
| | | |
| | | const { Title, Paragraph } = Typography; |
| | | |
| | | const CompanyQrCodeModal = ({ visible, onCancel }, ref) => { |
| | | const [loading, setLoading] = useState(false); |
| | | const [qrCodeUrl, setQrCodeUrl] = useState(''); |
| | | |
| | | useImperativeHandle(ref, () => { |
| | | return { |
| | | showQrCode: (url) => { |
| | | setQrCodeUrl(url); |
| | | setVisible(true); |
| | | }, |
| | | }; |
| | | }); |
| | | |
| | | const downloadQrCode = async () => { |
| | | if (!qrCodeUrl) return; |
| | | |
| | | setLoading(true); |
| | | try { |
| | | const response = await request(qrCodeUrl, { |
| | | method: 'GET', |
| | | responseType: 'blob', |
| | | }); |
| | | |
| | | const url = window.URL.createObjectURL(new Blob([response])); |
| | | const link = document.createElement('a'); |
| | | link.href = url; |
| | | link.setAttribute('download', `推广二维码.png`); |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | window.URL.revokeObjectURL(url); |
| | | } catch (error) { |
| | | console.error('下载二维码失败:', error); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | return ( |
| | | <Modal |
| | | getContainer={false} |
| | | width={500} |
| | | centered |
| | | destroyOnHidden |
| | | title="推广二维码" |
| | | open={visible} |
| | | onCancel={onCancel} |
| | | footer={ |
| | | <Space> |
| | | <Button onClick={onCancel}>关闭</Button> |
| | | {qrCodeUrl && ( |
| | | <Button |
| | | type="primary" |
| | | icon={<DownloadOutlined />} |
| | | loading={loading} |
| | | onClick={downloadQrCode} |
| | | > |
| | | 下载二维码 |
| | | </Button> |
| | | )} |
| | | </Space> |
| | | } |
| | | > |
| | | <div style={{ textAlign: 'center', padding: '20px 0' }}> |
| | | <Title level={4}>公司推广二维码</Title> |
| | | {qrCodeUrl ? ( |
| | | <div style={{ marginTop: 20 }}> |
| | | <img |
| | | src={qrCodeUrl} |
| | | alt="推广二维码" |
| | | style={{ maxWidth: '100%', height: 'auto', border: '1px solid #d9d9d9', borderRadius: 4 }} |
| | | /> |
| | | </div> |
| | | ) : ( |
| | | <Paragraph type="warning">暂无推广二维码</Paragraph> |
| | | )} |
| | | </div> |
| | | </Modal> |
| | | ); |
| | | }; |
| | | |
| | | export default forwardRef(CompanyQrCodeModal); |
| New file |
| | |
| | | import { ProTable } from '@ant-design/pro-components'; |
| | | import { useRef } from 'react'; |
| | | import { getCompanyUserList } from '../service'; |
| | | import { buildProTableDataSource } from '@/utils/antdUtils'; |
| | | |
| | | const CompanyUserManagement = () => { |
| | | const actionRef = useRef(); |
| | | |
| | | const columns = [ |
| | | { |
| | | title: '人员姓名', |
| | | dataIndex: 'nickName', |
| | | align: 'center', |
| | | width: 120, |
| | | }, |
| | | { |
| | | title: '推广ID', |
| | | dataIndex: 'code', |
| | | align: 'center', |
| | | width: 120, |
| | | }, |
| | | { |
| | | title: '手机号', |
| | | dataIndex: 'phonenumber', |
| | | align: 'center', |
| | | width: 130, |
| | | }, |
| | | { |
| | | title: '创建时间', |
| | | dataIndex: 'createTime', |
| | | align: 'center', |
| | | width: 160, |
| | | }, |
| | | { |
| | | title: '角色', |
| | | dataIndex: 'roleName', |
| | | align: 'center', |
| | | width: 100, |
| | | render: (roleName) => ( |
| | | <span>{roleName || '-'}</span> |
| | | ), |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <ProTable |
| | | rowKey="id" |
| | | columns={columns} |
| | | actionRef={actionRef} |
| | | cardBordered |
| | | request={async (params) => buildProTableDataSource(getCompanyUserList, params)} |
| | | search={false} |
| | | pagination={{ |
| | | defaultPageSize: 10, |
| | | showQuickJumper: true, |
| | | }} |
| | | /> |
| | | ); |
| | | }; |
| | | |
| | | export default CompanyUserManagement; |
| New file |
| | |
| | | import { Card, Descriptions, Tabs, Image } from 'antd'; |
| | | import { PageContainer } from '@ant-design/pro-components'; |
| | | import { useEffect, useState, useRef } from 'react'; |
| | | import { getCompanyDetail } from './service'; |
| | | import CompanyUserManagement from './components/CompanyUserManagement'; |
| | | import CompanyPromotionRecord from './components/CompanyPromotionRecord'; |
| | | import CompanyProfitDetail from './components/CompanyProfitDetail'; |
| | | import CompanyQrCodeModal from './components/CompanyQrCodeModal'; |
| | | |
| | | const CompanyInfo = () => { |
| | | const [companyInfo, setCompanyInfo] = useState({}); |
| | | const [loading, setLoading] = useState(true); |
| | | const [qrCodeModalVisible, setQrCodeModalVisible] = useState(false); |
| | | const qrCodeModalRef = useRef(); |
| | | |
| | | useEffect(() => { |
| | | fetchCompanyDetail(); |
| | | }, []); |
| | | |
| | | const fetchCompanyDetail = async () => { |
| | | try { |
| | | setLoading(true); |
| | | const res = await getCompanyDetail(); |
| | | if (res?.code === 200) { |
| | | setCompanyInfo(res.data); |
| | | |
| | | // 如果有推广二维码,显示二维码弹窗 |
| | | if (res.data.promotionQrCode) { |
| | | qrCodeModalRef.current?.showQrCode(res.data.promotionQrCode); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('获取公司详情失败:', error); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | const handleQrCodeClick = () => { |
| | | if (companyInfo.promotionQrCode) { |
| | | qrCodeModalRef.current?.showQrCode(companyInfo.promotionQrCode); |
| | | } |
| | | }; |
| | | |
| | | return ( |
| | | <PageContainer loading={loading}> |
| | | <div style={{ padding: '0 24px' }}> |
| | | <Card title="公司基本信息" style={{ marginBottom: 24 }}> |
| | | <Descriptions column={3} bordered> |
| | | <Descriptions.Item label="公司名称"> |
| | | {companyInfo.name || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="负责人"> |
| | | {companyInfo.chargePerson || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="联系方式"> |
| | | {companyInfo.chargePersonPhone || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="商户号"> |
| | | {companyInfo.merchantNumber || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="商户openId"> |
| | | {companyInfo.merchantOpenid || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="推广号"> |
| | | {companyInfo.code || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="所在地址" span={3}> |
| | | {companyInfo.address || '-'} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="推广二维码" span={3}> |
| | | {companyInfo.promotionQrCode ? ( |
| | | <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}> |
| | | <Image |
| | | src={companyInfo.promotionQrCode} |
| | | alt="推广二维码" |
| | | width={80} |
| | | height={80} |
| | | style={{ cursor: 'pointer', border: '1px solid #d9d9d9', borderRadius: 4 }} |
| | | onClick={handleQrCodeClick} |
| | | preview={false} |
| | | /> |
| | | <a onClick={handleQrCodeClick} style={{ color: '#1890ff' }}> |
| | | 查看并下载 |
| | | </a> |
| | | </div> |
| | | ) : ( |
| | | '-' |
| | | )} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="备注" span={3}> |
| | | {companyInfo.remark || '-'} |
| | | </Descriptions.Item> |
| | | </Descriptions> |
| | | </Card> |
| | | |
| | | <Card> |
| | | <Tabs |
| | | defaultActiveKey="1" |
| | | destroyOnHidden |
| | | items={[ |
| | | { |
| | | key: '1', |
| | | label: '管理人员列表', |
| | | children: <CompanyUserManagement companyId={companyInfo.id} />, |
| | | }, |
| | | { |
| | | key: '2', |
| | | label: '推广记录', |
| | | children: <CompanyPromotionRecord companyId={companyInfo.id} />, |
| | | }, |
| | | { |
| | | key: '3', |
| | | label: '收益明细', |
| | | children: <CompanyProfitDetail companyId={companyInfo.id} />, |
| | | }, |
| | | ]} |
| | | /> |
| | | </Card> |
| | | </div> |
| | | |
| | | <CompanyQrCodeModal |
| | | visible={qrCodeModalVisible} |
| | | onCancel={() => setQrCodeModalVisible(false)} |
| | | ref={qrCodeModalRef} |
| | | /> |
| | | </PageContainer> |
| | | ); |
| | | }; |
| | | |
| | | export default CompanyInfo; |
| New file |
| | |
| | | import { request } from '@umijs/max'; |
| | | |
| | | // 获取公司详情 |
| | | export const getCompanyDetail = async () => { |
| | | return request('/agent/company/detail', { |
| | | method: 'GET', |
| | | }); |
| | | }; |
| | | |
| | | // 获取管理人员列表 |
| | | export const getCompanyUserList = async (data) => { |
| | | return request('/agent/company/getCompanyUserList', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // 获取推广记录列表 |
| | | export const getPromotionPageList = async (data) => { |
| | | return request('/agent/company/promotionPageList', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // 获取收益明细列表 |
| | | export const getProfitPageList = async (data) => { |
| | | return request('/agent/company/profitPageList', { |
| | | method: 'POST', |
| | | data, |
| | | }); |
| | | }; |
| New file |
| | |
| | | import { getRefundRecordsDetail } from '../service'; |
| | | import { Modal, Descriptions, Image, Table, Typography } from 'antd'; |
| | | import { useEffect, useState } from 'react'; |
| | | import moment from 'moment'; |
| | | |
| | | const { Text } = Typography; |
| | | |
| | | const RefundDetailModal = ({ visible, onCancel, id }) => { |
| | | const [orderDetail, setOrderDetail] = useState(null); |
| | | const [loading, setLoading] = useState(false); |
| | | |
| | | // 订单状态映射 |
| | | const statusMap = { |
| | | 1: '待付款', |
| | | 2: '已付订金', |
| | | 3: '完成支付', |
| | | 4: '确认收货', |
| | | 5: '已退款', |
| | | 6: '已取消', |
| | | }; |
| | | |
| | | // 审核状态映射 |
| | | const auditStatusMap = { |
| | | 1: '待审核', |
| | | 2: '审核通过', |
| | | 3: '审核驳回', |
| | | }; |
| | | |
| | | // 支付类型映射 |
| | | const paymentTypeMap = { |
| | | 1: '订金+尾款', |
| | | 2: '全款', |
| | | }; |
| | | |
| | | // 获取订单详情 |
| | | const fetchOrderDetail = async () => { |
| | | if (!id) return; |
| | | |
| | | setLoading(true); |
| | | try { |
| | | const res = await getRefundRecordsDetail(id); |
| | | if (res.code === 200 && res.data) { |
| | | setOrderDetail(res.data); |
| | | } |
| | | } catch (error) { |
| | | console.error('获取订单详情失败:', error); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | if (visible && id) { |
| | | fetchOrderDetail(); |
| | | } |
| | | }, [visible, id]); |
| | | |
| | | // 渲染商品信息表格 |
| | | const renderProductTable = () => { |
| | | const columns = [ |
| | | { |
| | | title: '商品名称', |
| | | dataIndex: 'bigGiftPackageName', |
| | | width: 200, |
| | | ellipsis: true, |
| | | }, |
| | | { |
| | | title: '封面图', |
| | | dataIndex: 'bigGiftPackageCover', |
| | | width: 100, |
| | | render: (text) => ( |
| | | <Image |
| | | width={60} |
| | | height={60} |
| | | src={text ? IMAGE_URL + text : null} |
| | | style={{ objectFit: 'cover' }} |
| | | placeholder={<div style={{ width: 60, height: 60, background: '#f5f5f5' }} />} |
| | | fallback="/images/default-image.png" |
| | | /> |
| | | ), |
| | | }, |
| | | { |
| | | title: '商品价格', |
| | | dataIndex: 'bigGiftPackagePrice', |
| | | width: 120, |
| | | render: (text) => `¥${text || 0}`, |
| | | }, |
| | | { |
| | | title: '商品简介', |
| | | dataIndex: 'bigGiftPackageIntro', |
| | | ellipsis: true, |
| | | }, |
| | | { |
| | | title: '销量', |
| | | dataIndex: 'bigGiftPackageSales', |
| | | width: 80, |
| | | }, |
| | | ]; |
| | | |
| | | const dataSource = [{ |
| | | key: orderDetail?.id, |
| | | ...orderDetail, |
| | | }]; |
| | | |
| | | return ( |
| | | <Table |
| | | columns={columns} |
| | | dataSource={dataSource} |
| | | pagination={false} |
| | | size="small" |
| | | /> |
| | | ); |
| | | }; |
| | | |
| | | // 渲染详情内容 |
| | | const renderDetailContent = () => { |
| | | if (!orderDetail) return null; |
| | | |
| | | const { status, paymentType, auditStatus } = orderDetail; |
| | | |
| | | // 基础字段(所有状态都显示) |
| | | const baseItems = [ |
| | | { |
| | | label: '订单编号', |
| | | children: orderDetail.code || '-', |
| | | }, |
| | | { |
| | | label: '下单时间', |
| | | children: orderDetail.createTime ? moment(orderDetail.createTime).format('YYYY-MM-DD HH:mm:ss') : '-', |
| | | }, |
| | | { |
| | | label: '用户昵称', |
| | | children: orderDetail.userName || '-', |
| | | }, |
| | | { |
| | | label: '用户手机号', |
| | | children: orderDetail.phone || '-', |
| | | }, |
| | | { |
| | | label: '订单状态', |
| | | children: statusMap[status] || '-', |
| | | }, |
| | | { |
| | | label: '审核状态', |
| | | children: ( |
| | | <span style={{ |
| | | color: |
| | | auditStatus === 1 ? '#faad14' : |
| | | auditStatus === 2 ? '#52c41a' : |
| | | '#f5222d' |
| | | }}> |
| | | {auditStatusMap[auditStatus] || auditStatus} |
| | | </span> |
| | | ), |
| | | }, |
| | | { |
| | | label: '订单金额', |
| | | children: `¥${orderDetail.orderPrice || 0}`, |
| | | }, |
| | | { |
| | | label: '支付方式', |
| | | children: paymentTypeMap[paymentType] || '-', |
| | | }, |
| | | ]; |
| | | |
| | | // 根据不同状态添加特定字段 |
| | | let specificItems = []; |
| | | |
| | | if (status >= 2) { |
| | | // 已付定金或更高级状态 |
| | | specificItems = [ |
| | | { |
| | | label: '定金', |
| | | children: `¥${orderDetail.deposit || 0}`, |
| | | }, |
| | | { |
| | | label: '定金支付方式', |
| | | children: '微信支付', |
| | | }, |
| | | { |
| | | label: '定金支付时间', |
| | | children: orderDetail.depositTime ? moment(orderDetail.depositTime).format('YYYY-MM-DD HH:mm:ss') : '-', |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | if (status === 3 && paymentType === 1) { |
| | | // 已支付定金+尾款 |
| | | specificItems = [ |
| | | ...specificItems, |
| | | { |
| | | label: '已付尾款', |
| | | children: `¥${orderDetail.finalPayment || 0}`, |
| | | }, |
| | | { |
| | | label: '尾款支付方式', |
| | | children: '微信支付', |
| | | }, |
| | | { |
| | | label: '尾款支付时间', |
| | | children: orderDetail.finalPaymentTime ? moment(orderDetail.finalPaymentTime).format('YYYY-MM-DD HH:mm:ss') : '-', |
| | | }, |
| | | ]; |
| | | } else if (status === 3 && paymentType === 2) { |
| | | // 已支付全款 |
| | | specificItems = [ |
| | | { |
| | | label: '支付金额', |
| | | children: `¥${orderDetail.paymentPrice || 0}`, |
| | | }, |
| | | { |
| | | label: '支付时间', |
| | | children: orderDetail.depositTime ? moment(orderDetail.depositTime).format('YYYY-MM-DD HH:mm:ss') : '-', |
| | | }, |
| | | { |
| | | label: '支付方式', |
| | | children: '微信支付', |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | // 退款相关字段 |
| | | const refundItems = [ |
| | | { |
| | | label: '退款金额', |
| | | children: `¥${orderDetail.refundAmount || '0.00'}`, |
| | | }, |
| | | { |
| | | label: '申请退款原因', |
| | | children: orderDetail.refundReason || '-', |
| | | }, |
| | | ]; |
| | | |
| | | // 审核相关字段 |
| | | const auditItems = []; |
| | | if (auditStatus >= 2) { |
| | | auditItems.push( |
| | | { |
| | | label: '审核结果', |
| | | children: auditStatus === 2 ? '审核通过' : '审核驳回', |
| | | }, |
| | | { |
| | | label: '审核时间', |
| | | children: orderDetail.auditTime ? moment(orderDetail.auditTime).format('YYYY-MM-DD HH:mm:ss') : '-', |
| | | }, |
| | | { |
| | | label: '审核人', |
| | | children: orderDetail.auditorName || '-', |
| | | }, |
| | | { |
| | | label: '审核意见', |
| | | children: orderDetail.auditRemark || '-', |
| | | }, |
| | | ); |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <Descriptions column={2} bordered loading={loading}> |
| | | {[...baseItems, ...specificItems, ...refundItems, ...auditItems].map((item, index) => ( |
| | | <Descriptions.Item key={index} label={item.label}> |
| | | {item.children} |
| | | </Descriptions.Item> |
| | | ))} |
| | | </Descriptions> |
| | | |
| | | {/* 商品信息 */} |
| | | <div style={{ marginTop: 24 }}> |
| | | <Text strong>商品信息</Text> |
| | | <div style={{ marginTop: 8 }}> |
| | | {renderProductTable()} |
| | | </div> |
| | | </div> |
| | | |
| | | {/* 图片凭证 */} |
| | | {orderDetail.refundImages && ( |
| | | <div style={{ marginTop: 24 }}> |
| | | <Text strong>图片凭证</Text> |
| | | <div style={{ marginTop: 8, display: 'flex', gap: 8, flexWrap: 'wrap' }}> |
| | | {orderDetail.refundImages.split(',').map((img, index) => ( |
| | | <Image |
| | | key={index} |
| | | width={80} |
| | | height={80} |
| | | src={img} |
| | | alt={`凭证${index + 1}`} |
| | | style={{ objectFit: 'cover' }} |
| | | fallback="/images/default-image.png" |
| | | /> |
| | | ))} |
| | | </div> |
| | | </div> |
| | | )} |
| | | |
| | | {/* 备注 */} |
| | | {orderDetail.remark && ( |
| | | <div style={{ marginTop: 24 }}> |
| | | <Text strong>备注</Text> |
| | | <div style={{ marginTop: 8 }}> |
| | | {orderDetail.remark} |
| | | </div> |
| | | </div> |
| | | )} |
| | | </div> |
| | | ); |
| | | }; |
| | | |
| | | return ( |
| | | <Modal |
| | | title="退款申请详情" |
| | | open={visible} |
| | | onCancel={onCancel} |
| | | footer={[ |
| | | <button key="close" type="button" className="ant-btn" onClick={onCancel}> |
| | | 关闭 |
| | | </button>, |
| | | ]} |
| | | width={800} |
| | | destroyOnHidden |
| | | > |
| | | {renderDetailContent()} |
| | | </Modal> |
| | | ); |
| | | }; |
| | | |
| | | export default RefundDetailModal; |
| New file |
| | |
| | | import { Button } from 'antd'; |
| | | import { useRef, useState } from 'react'; |
| | | import { PageContainer, ProTable } from '@ant-design/pro-components'; |
| | | import RefundDetailModal from './components/RefundDetailModal'; |
| | | import { getRefundRecordsList } from './service'; |
| | | import { buildProTableDataSource } from '@/utils/antdUtils'; |
| | | |
| | | const RefundRecords = () => { |
| | | const actionRef = useRef(); |
| | | const [detailVisible, setDetailVisible] = useState(false); |
| | | const [currentId, setCurrentId] = useState(null); |
| | | |
| | | // 状态映射 |
| | | const auditStatusMap = { |
| | | 1: { text: '待审核', status: 'Warning' }, |
| | | 2: { text: '审核通过', status: 'Success' }, |
| | | 3: { text: '审核驳回', status: 'Error' }, |
| | | }; |
| | | |
| | | const paymentTypeMap = { |
| | | 1: '订金+尾款', |
| | | 2: '全款', |
| | | }; |
| | | |
| | | const columns = [ |
| | | { |
| | | title: '序号', |
| | | dataIndex: 'index', |
| | | hideInSearch: true, |
| | | width: 60, |
| | | render: (text, record, index) => index + 1, |
| | | }, |
| | | { |
| | | title: '订单编号', |
| | | dataIndex: 'code', |
| | | width: 180, |
| | | copyable: true, |
| | | ellipsis: true, |
| | | order: 4, |
| | | search: { |
| | | transform: (value) => ({ |
| | | code: value, |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | title: '下单时间', |
| | | dataIndex: 'createTime', |
| | | valueType: 'dateRange', |
| | | width: 240, |
| | | order: 2, |
| | | search: { |
| | | transform: (value) => ({ |
| | | time: value ? value.join(' - ') : undefined, |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | title: '用户手机号', |
| | | dataIndex: 'phone', |
| | | width: 120, |
| | | order: 3, |
| | | search: { |
| | | transform: (value) => ({ |
| | | phone: value, |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | title: '下单用户', |
| | | dataIndex: 'userName', |
| | | hideInSearch: true, |
| | | width: 120, |
| | | ellipsis: true, |
| | | }, |
| | | { |
| | | title: '订单价格', |
| | | dataIndex: 'orderPrice', |
| | | hideInSearch: true, |
| | | width: 100, |
| | | render: (text) => `¥${text}`, |
| | | search: false, |
| | | }, |
| | | { |
| | | title: '商品名称', |
| | | dataIndex: 'bigGiftPackageName', |
| | | width: 200, |
| | | hideInSearch: true, |
| | | ellipsis: true, |
| | | search: { |
| | | transform: (value) => ({ |
| | | name: value, |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | title: '支付方式', |
| | | dataIndex: 'paymentType', |
| | | hideInSearch: true, |
| | | valueType: 'select', |
| | | valueEnum: paymentTypeMap, |
| | | width: 120, |
| | | }, |
| | | { |
| | | title: '审核状态', |
| | | dataIndex: 'auditStatus', |
| | | valueType: 'select', |
| | | valueEnum: auditStatusMap, |
| | | order: 1, |
| | | width: 120, |
| | | search: { |
| | | transform: (value) => ({ |
| | | auditStatus: value, |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | title: '操作', |
| | | dataIndex: 'action', |
| | | valueType: 'option', |
| | | width: 100, |
| | | fixed: 'right', |
| | | render: (_, record) => ( |
| | | <Button |
| | | type="link" |
| | | size="small" |
| | | onClick={() => { |
| | | setCurrentId(record.id); |
| | | setDetailVisible(true); |
| | | }} |
| | | > |
| | | 详情 |
| | | </Button> |
| | | ), |
| | | }, |
| | | ]; |
| | | |
| | | return ( |
| | | <PageContainer> |
| | | <ProTable |
| | | actionRef={actionRef} |
| | | rowKey="id" |
| | | search={{ |
| | | labelWidth: 'auto', |
| | | defaultCollapsed: false, |
| | | }} |
| | | request={(params) => buildProTableDataSource(getRefundRecordsList, params)} |
| | | columns={columns} |
| | | scroll={{ x: 1400 }} |
| | | pagination={{ |
| | | showSizeChanger: true, |
| | | showQuickJumper: true, |
| | | defaultPageSize: 10, |
| | | }} |
| | | /> |
| | | |
| | | {/* 详情弹窗 */} |
| | | <RefundDetailModal |
| | | visible={detailVisible} |
| | | onCancel={() => { |
| | | setDetailVisible(false); |
| | | setCurrentId(null); |
| | | }} |
| | | id={currentId} |
| | | /> |
| | | </PageContainer> |
| | | ); |
| | | }; |
| | | |
| | | export default RefundRecords; |
| New file |
| | |
| | | import { request } from '@umijs/max'; |
| | | |
| | | // 获取退款申请记录列表 |
| | | export async function getRefundRecordsList(params) { |
| | | return request('/agent/t-big-gift-package-order/refundList', { |
| | | method: 'POST', |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | // 获取退款申请记录详情 |
| | | export async function getRefundRecordsDetail(id) { |
| | | return request(`/agent/t-big-gift-package-order/refundDetail/${id}`, { |
| | | method: 'GET', |
| | | }); |
| | | } |