| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388 |
- <template>
- <div v-loading="pageLoading" class="app-container" :element-loading-text="loadingText">
- <el-tabs v-model="activeTab" class="account-tabs" type="card">
- <el-tab-pane label="账户概览" name="overview">
- <AccountOverview ref="overviewRef" :enterprise-id="currentEnterpriseId" @refresh="handleOverviewRefresh"
- @goTab="handleGoTab" />
- </el-tab-pane>
- <!-- <el-tab-pane label="转账授权签约" name="authorize">
- <div class="tab-content">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>转账授权签约</span>
- </div>
- </template>
- <el-form ref="authorizeFormRef" :model="authorizeForm" :rules="authorizeRules" label-width="120px">
- <el-form-item label="企业ID" prop="enterprise_id" v-show="!currentEnterpriseId">
- <el-input v-model="authorizeForm.enterprise_id" placeholder="请输入企业ID" :disabled="!!currentEnterpriseId" />
- </el-form-item>
- <el-form-item>
- <el-button v-hasPerm="['module_payment:account:authorize']" type="primary" :loading="authorizeLoading"
- @click="handleAuthorize">
- 申请签约
- </el-button>
- <el-button @click="handleAuthorizeReset">重置</el-button>
- </el-form-item>
- </el-form>
- <div v-if="authorizeResult.sign_url" class="authorize-result">
- <el-alert title="签约链接已生成,请在支付宝中完成签约" type="success" :closable="false">
- <template #default>
- <el-link :href="authorizeResult.sign_url" target="_blank" type="primary">
- 点击前往签约 →
- </el-link>
- </template>
- </el-alert>
- </div>
- </el-card>
- </div>
- </el-tab-pane> -->
- <!-- <el-tab-pane label="开通资金专户" name="create">
- <div class="tab-content">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>开通资金专户</span>
- <el-tag v-if="authorizeStatus !== 'AUTHORIZED'" type="danger">
- 请先完成转账授权签约
- </el-tag>
- </div>
- </template>
- <el-form
- ref="createFormRef"
- :model="createForm"
- :rules="createRules"
- label-width="140px"
- >
- <el-form-item label="企业ID" prop="enterprise_id">
- <el-input
- v-model="createForm.enterprise_id"
- placeholder="请输入企业ID"
- :disabled="!!currentEnterpriseId"
- />
- </el-form-item>
- <el-form-item label="账户类型" prop="account_type">
- <el-select v-model="createForm.account_type" placeholder="请选择账户类型">
- <el-option label="收支全能户" value="ALL" />
- <el-option label="收入户" value="INCOME" />
- <el-option label="支出户" value="DISBURSE" />
- </el-select>
- </el-form-item>
- <el-form-item label="场景类型" prop="scene">
- <el-select v-model="createForm.scene" placeholder="请选择场景类型">
- <el-option label="ToB转账" value="B2B_TRANS" />
- <el-option label="企业信用" value="ENT_CREDIT" />
- </el-select>
- </el-form-item>
- <el-form-item label="备注" prop="remark">
- <el-input v-model="createForm.remark" type="textarea" placeholder="请输入备注" />
- </el-form-item>
- <el-form-item>
- <el-button
- v-hasPerm="['module_payment:account:create']"
- type="primary"
- :loading="createLoading"
- :disabled="authorizeStatus !== 'AUTHORIZED'"
- @click="handleCreate"
- >
- 开通专户
- </el-button>
- <el-button @click="handleCreateReset">重置</el-button>
- </el-form-item>
- </el-form>
- <div v-if="createResult.account_book_id" class="create-result">
- <el-alert title="资金专户开通成功" type="success" :closable="false">
- <template #default>
- <div>专户ID: {{ createResult.account_book_id }}</div>
- </template>
- </el-alert>
- </div>
- </el-card>
- </div>
- </el-tab-pane> -->
- <el-tab-pane label="账户充值" name="deposit">
- <div class="tab-content">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>资金专户充值</span>
- <el-tag v-if="!accountInfo.account_book_id" type="danger">
- 请先开通资金专户
- </el-tag>
- <!-- <el-tag v-else-if="accountInfo.status !== 'AUTHORIZED'" type="warning">
- 资金专户状态异常
- </el-tag> -->
- </div>
- </template>
- <el-form ref="depositFormRef" :model="depositForm" :rules="depositRules" label-width="140px">
- <!-- <el-form-item label="企业ID" prop="enterprise_id">
- <el-input v-model="currentEnterpriseId" placeholder="请输入企业ID" :disabled="!!currentEnterpriseId" />
- </el-form-item> -->
- <!-- <el-form-item label="资金账户" prop="account_book_id">
- <el-input v-model="depositForm.account_book_id" :placeholder="accountInfo.account_book_id || '请先开通资金账户'"
- :disabled="!!accountInfo.account_book_id" />
- </el-form-item> -->
- <el-form-item label="充值金额" prop="amount">
- <el-input-number v-model="depositForm.amount" :min="0.00" :precision="2" :controls="false"
- placeholder="请输入充值金额" style="width: 300px" />
- <span class="ml-2">元</span>
- </el-form-item>
- <!-- <el-form-item label="备注" prop="remark">
- <el-input v-model="depositForm.remark" type="textarea" placeholder="请输入备注" />
- </el-form-item> -->
- <el-form-item>
- <el-button v-hasPerm="['module_payment:account:deposit']" type="primary" :loading="depositLoading"
- :disabled="!accountInfo.account_book_id || accountInfo.status === 'AUTHORIZED'" @click="handleDeposit">
- 发起充值
- </el-button>
- <el-button @click="handleDepositReset">重置</el-button>
- </el-form-item>
- </el-form>
- <div v-if="depositResult.url" class="deposit-result">
- <el-alert title="充值页面已生成,请在支付宝中完成支付" type="success" :closable="false">
- <template #default>
- <el-link :href="depositResult.url" target="_blank" type="primary">
- 点击前往充值 →
- </el-link>
- </template>
- </el-alert>
- </div>
- </el-card>
- <!-- <el-card class="mt-4">
- <template #header>
- <span>充值记录</span>
- </template>
- <el-table :data="depositList" border stripe>
- <el-table-column prop="out_biz_no" label="订单号" min-width="180" />
- <el-table-column prop="amount" label="充值金额" min-width="100">
- <template #default="{ row }">
- ¥{{ row.amount }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="状态" min-width="100">
- <template #default="{ row }">
- <el-tag :type="getDepositStatusType(row.status)">
- {{ row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="created_time" label="创建时间" min-width="160" />
- </el-table>
- </el-card> -->
- </div>
- </el-tab-pane>
- <el-tab-pane label="转账管理" name="transfer">
- <div class="tab-content">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>发起转账</span>
- <div>
- <el-tag v-if="!accountInfo.account_book_id" type="danger" class="ml-2">
- 请先开通资金专户
- </el-tag>
- <el-tag v-else-if="accountInfo.balance <= 0" type="warning" class="ml-2">
- 账户余额不足,请先充值
- </el-tag>
- </div>
- </div>
- </template>
- <el-form ref="transferFormRef" :model="transferForm" :rules="transferRules" label-width="140px">
- <!-- <el-form-item label="企业ID" prop="enterprise_id">
- <el-input v-model="currentEnterpriseId" placeholder="请输入企业ID"
- :disabled="!!currentEnterpriseId" />
- </el-form-item>
- <el-form-item label="付款资金账户" prop="account_book_id">
- <el-input v-model="transferForm.account_book_id"
- :placeholder="accountInfo.account_book_id || '请先开通资金账户'" :disabled="!!accountInfo.account_book_id" />
- </el-form-item> -->
- <el-form-item label="转账金额" prop="amount">
- <el-input-number v-model="transferForm.amount" :min="0.00" :precision="2" :controls="false"
- placeholder="请输入转账金额" style="width: 300px" />
- <span class="ml-2">元</span>
- </el-form-item>
- <el-form-item label="转账标题" prop="order_title">
- <el-input v-model="transferForm.order_title" placeholder="请输入转账标题" />
- </el-form-item>
- <el-form-item label="收款方类型" prop="payee_info.identity_type">
- <el-select v-model="transferForm.payee_info.identity_type" placeholder="请选择收款方类型">
- <el-option label="支付宝账户" value="alipay" />
- <el-option label="银行卡" value="bank" />
- <!-- <el-option label="资金专户" value="book" /> -->
- </el-select>
- </el-form-item>
- <el-form-item label="收款方真实姓名" prop="payee_info.name">
- <el-input v-model="transferForm.payee_info.name" placeholder="请输入收款方姓名" />
- </el-form-item>
- <el-form-item :label="transferForm.payee_info.identity_type === 'alipay' ? '收款方支付宝账号' : '收款方银行卡号'" prop="payee_info.identity">
- <el-input v-model="transferForm.payee_info.identity" :placeholder="transferForm.payee_info.identity_type === 'alipay' ? '请输入收款方支付宝账号' : '请输入收款方银行卡号'" />
- </el-form-item>
- <template v-if="transferForm.payee_info.identity_type === 'bank'">
- <el-form-item label="账户类型" prop="payee_info.bankcard_ext_info.account_type">
- <el-select v-model="transferForm.payee_info.bankcard_ext_info!.account_type" placeholder="请选择账户类型">
- <el-option label="公司账户" value="1" />
- <el-option label="个人账户" value="2" />
- </el-select>
- </el-form-item>
- <el-form-item label="银行名称" prop="payee_info.bankcard_ext_info.inst_name">
- <el-input v-model="transferForm.payee_info.bankcard_ext_info!.inst_name" placeholder="请输入银行名称" />
- </el-form-item>
- <el-form-item label="开户省份" prop="payee_info.bankcard_ext_info.inst_province">
- <el-input v-model="transferForm.payee_info.bankcard_ext_info!.inst_province" placeholder="请输入开户省份" />
- </el-form-item>
- <el-form-item label="开户城市" prop="payee_info.bankcard_ext_info.inst_city">
- <el-input v-model="transferForm.payee_info.bankcard_ext_info!.inst_city" placeholder="请输入开户城市" />
- </el-form-item>
- <el-form-item label="支行名称" prop="payee_info.bankcard_ext_info.inst_branch_name">
- <el-input v-model="transferForm.payee_info.bankcard_ext_info!.inst_branch_name"
- placeholder="请输入支行名称" />
- </el-form-item>
- <el-form-item label="联行号" prop="payee_info.bankcard_ext_info.bank_code">
- <el-input v-model="transferForm.payee_info.bankcard_ext_info!.bank_code" placeholder="请输入联行号" />
- </el-form-item>
- </template>
- <el-form-item label="备注" prop="remark">
- <el-input v-model="transferForm.remark" type="textarea" placeholder="请输入备注" />
- </el-form-item>
- <el-form-item>
- <el-button v-hasPerm="['module_payment:account:transfer']" type="primary" :loading="transferLoading"
- :disabled="!accountInfo.account_book_id || accountInfo.balance <= 0" @click="handleTransfer">
- 发起转账
- </el-button>
- <el-button @click="handleTransferReset">重置</el-button>
- <el-button v-hasPerm="['module_payment:account:transfer']" type="primary" @click="openBatchTransferDialog">
- 批量转账
- </el-button>
- </el-form-item>
- </el-form>
- </el-card>
- <el-card class="mt-4">
- <template #header>
- <div class="card-header">
- <span>转账记录</span>
- </div>
- </template>
- <div class="mb-4">
- <el-form :inline="true" :model="transferSearchForm">
- <el-form-item label="订单号">
- <el-input v-model="transferSearchForm.out_biz_no" placeholder="请输入订单号" clearable />
- </el-form-item>
- <el-form-item label="状态">
- <el-select v-model="transferSearchForm.status" placeholder="请选择状态" clearable>
- <el-option label="处理中" value="DEALING" />
- <el-option label="成功" value="SUCCESS" />
- <el-option label="失败" value="FAIL" />
- <el-option label="退票" value="REFUND" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleTransferSearch">查询</el-button>
- <el-button @click="handleTransferSearchReset">重置</el-button>
- <el-button icon="Refresh" @click="handleTransferSearchReset">刷新</el-button>
- </el-form-item>
- </el-form>
- </div>
- <el-table :data="transferList" border stripe v-loading="transferListLoading">
- <template #empty>
- <el-empty description="暂无数据" />
- </template>
- <el-table-column prop="out_biz_no" label="订单号" min-width="180" />
- <el-table-column prop="amount" label="转账金额" min-width="100">
- <template #default="{ row }">
- ¥{{ row.amount }}
- </template>
- </el-table-column>
- <el-table-column prop="payee_info.name" label="收款方姓名" min-width="120" />
- <el-table-column prop="payee_info.identity_type" label="收款方类型" min-width="100">
- <template #default="{ row }">
- {{ getPayeeTypeLabel(row.payee_info?.identity_type) }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="状态" min-width="100">
- <template #default="{ row }">
- <el-tag :type="getTransferStatusType(row.status)">
- {{ getStatusLabel(row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="order_title" label="转账标题" min-width="150" />
- <el-table-column prop="created_time" label="创建时间" min-width="160" />
- <el-table-column label="操作" width="100" fixed="right">
- <template #default="{ row }">
- <el-button type="primary" link @click="handleViewTransferDetail(row.out_biz_no)">
- 详情
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <div class="mt-4 flex justify-end">
- <el-pagination v-model:current-page="transferPage.page_no" v-model:page-size="transferPage.page_size"
- :total="transferPage.total" :page-sizes="[10, 20, 50, 100]"
- layout="total, sizes, prev, pager, next, jumper" @size-change="handleTransferListChange"
- @current-change="handleTransferListChange" />
- </div>
- </el-card>
- </div>
- </el-tab-pane>
- <!-- <el-tab-pane label="账单查询" name="consume">
- <div class="tab-content">
- <el-card>
- <template #header>
- <span>账单详情查询</span>
- </template>
- <el-form ref="consumeFormRef" :model="consumeForm" :rules="consumeRules" label-width="140px">
- <el-form-item label="支付宝账单号" prop="pay_no">
- <el-input v-model="consumeForm.pay_no" placeholder="请输入支付宝账单号" />
- </el-form-item>
- <el-form-item label="企业ID" prop="enterprise_id">
- <el-input
- v-model="consumeForm.enterprise_id"
- placeholder="请输入企业ID(2.0接口签约企业必填)"
- :disabled="!!currentEnterpriseId"
- />
- </el-form-item>
- <el-form-item label="蚂蚁门店ID" prop="ant_shop_id">
- <el-input v-model="consumeForm.ant_shop_id" placeholder="请输入蚂蚁门店ID(商户服务商必填)" />
- </el-form-item>
- <el-form-item label="查询选项">
- <el-checkbox-group v-model="consumeForm.query_options">
- <el-checkbox label="Refund">退款信息</el-checkbox>
- <el-checkbox label="Order">订单信息</el-checkbox>
- <el-checkbox label="Ticket">票据信息</el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- <el-form-item>
- <el-button
- v-hasPerm="['module_payment:account:consume:detail']"
- type="primary"
- :loading="consumeLoading"
- @click="handleConsumeQuery"
- >
- 查询
- </el-button>
- <el-button @click="handleConsumeReset">重置</el-button>
- </el-form-item>
- </el-form>
- </el-card>
- <el-card v-if="consumeDetail" class="mt-4">
- <template #header>
- <span>账单详情</span>
- </template>
- <ConsumeDetail :data="consumeDetail" />
- </el-card>
- </div>
- </el-tab-pane> -->
- </el-tabs>
- <TransferDetail v-model="transferDetailVisible" :out-biz-no="currentTransferOutBizNo"
- @refresh="handleTransferDetailRefresh" />
- <!-- 批量转账对话框 -->
- <el-dialog v-model="batchTransferVisible" title="批量转账" width="1000px" :close-on-click-modal="false" :close-on-press-escape="false">
- <div class="batch-transfer-container" :class="{ 'has-overlay': showBatchTransferOverlay }">
- <el-card class="mb-4">
- <template #header>
- <span>Excel模板下载</span>
- </template>
- <el-button type="primary" @click="downloadTemplate">下载模板</el-button>
- <el-alert
- title="模板说明"
- type="info"
- :closable="false"
- class="mt-4"
- >
- <ul>
- <li>请按照模板格式填写转账数据</li>
- <li>支持支付宝账户和银行卡转账</li>
- <li>银行卡转账需要填写完整的银行信息</li>
- </ul>
- </el-alert>
- </el-card>
- <el-card class="mb-4">
- <template #header>
- <span>上传Excel文件</span>
- </template>
- <el-upload
- class="upload-demo"
- action=""
- :auto-upload="false"
- :on-change="handleFileChange"
- accept=".xlsx, .xls"
- :file-list="fileList"
- :limit="1"
- >
- <el-button type="primary">选择文件</el-button>
- <template #tip>
- <div class="el-upload__tip">
- 请上传Excel文件,支持.xlsx和.xls格式
- </div>
- </template>
- </el-upload>
- </el-card>
- <el-card v-if="batchTransferData.length > 0">
- <template #header>
- <span>数据预览</span>
- </template>
- <el-table :data="batchTransferData" border stripe>
- <el-table-column prop="amount" label="转账金额(元)" min-width="100" />
- <el-table-column prop="order_title" label="转账标题" min-width="150" />
- <el-table-column prop="payee_name" label="收款方姓名" min-width="120" />
- <el-table-column prop="payee_type" label="收款方类型" min-width="100" />
- <el-table-column prop="payee_account" label="收款方账号" min-width="180" />
- <el-table-column prop="bank_name" label="银行名称" min-width="120" v-if="hasBankTransfer" />
- <el-table-column prop="status" label="状态" min-width="100">
- <template #default="{ row }">
- <el-tag :type="row.status === 'valid' ? 'success' : 'danger'">
- {{ row.status === 'valid' ? '有效' : '无效' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="error_msg" label="错误信息" min-width="150" v-if="hasInvalidData" />
- </el-table>
- </el-card>
- <!-- 遮罩层 -->
- <div v-if="showBatchTransferOverlay" class="batch-transfer-overlay">
- <div class="overlay-content">
- <el-icon class="is-loading" size="40"><Loading /></el-icon>
- <h3>正在处理批量转账,请勿关闭对话框</h3>
- <el-progress :percentage="Math.round((batchCurrentIndex / batchTotalCount) * 100)" :stroke-width="20" />
- <p>正在向 {{ batchCurrentPayee }} 转账 ¥{{ batchCurrentAmount }}</p>
- <div class="result-summary">
- <el-tag type="success">成功: {{ batchTransferSuccessCount }}</el-tag>
- <el-tag type="danger">失败: {{ batchTransferFailCount }}</el-tag>
- <el-tag type="warning">进行中: {{ batchCurrentIndex }}/{{ batchTotalCount }}</el-tag>
- </div>
- </div>
- </div>
- </div>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="batchTransferVisible = false" :disabled="batchTransferLoading">取消</el-button>
- <el-button type="primary" :loading="batchTransferLoading" @click="handleBatchTransfer" :disabled="batchTransferData.length === 0 || hasInvalidData || showBatchTransferOverlay">
- 开始批量转账
- </el-button>
- </span>
- </template>
- </el-dialog>
- <!-- 批量转账结果对话框 -->
- <el-dialog v-model="batchTransferResultVisible" title="批量转账结果" width="800px">
- <el-card>
- <template #header>
- <div class="card-header">
- <span>处理结果</span>
- <div>
- <el-tag type="success" class="ml-2">{{ batchTransferSuccessCount }} 成功</el-tag>
- <el-tag type="danger" class="ml-2">{{ batchTransferFailCount }} 失败</el-tag>
- </div>
- </div>
- </template>
- <el-table :data="batchTransferResults" border stripe>
- <el-table-column prop="amount" label="转账金额(元)" min-width="100" />
- <el-table-column prop="payee_name" label="收款方姓名" min-width="120" />
- <el-table-column prop="status" label="状态" min-width="100">
- <template #default="{ row }">
- <el-tag :type="row.status === 'success' ? 'success' : 'danger'">
- {{ row.status === 'success' ? '成功' : '失败' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="message" label="消息" min-width="200" />
- </el-table>
- </el-card>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="batchTransferResultVisible = false">关闭</el-button>
- </span>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- defineOptions({
- name: "Account",
- inheritAttrs: false,
- });
- import { useEnterpriseStore } from "@/store/modules/enterprise.store";
- import AccountAPI from "@/api/module_payment/account";
- import AccountOverview from "./components/AccountOverview.vue";
- import TransferDetail from "./components/TransferDetail.vue";
- import ConsumeDetail from "./components/ConsumeDetail.vue";
- import { ref, reactive, computed, onMounted, watch } from "vue";
- import { Refresh, Loading } from "@element-plus/icons-vue";
- import { ElMessage, ElMessageBox } from "element-plus";
- import type { FormInstance, FormRules } from "element-plus";
- import * as ExcelJS from "exceljs";
- const enterpriseStore = useEnterpriseStore();
- const activeTab = ref("overview");
- const pageLoading = ref(false);
- const loadingText = ref("加载中...");
- const authorizeLoading = ref(false);
- const createLoading = ref(false);
- const depositLoading = ref(false);
- const transferLoading = ref(false);
- const consumeLoading = ref(false);
- const transferListLoading = ref(false);
- const authorizeFormRef = ref<FormInstance>();
- const createFormRef = ref<FormInstance>();
- const depositFormRef = ref<FormInstance>();
- const transferFormRef = ref<FormInstance>();
- const consumeFormRef = ref<FormInstance>();
- const overviewRef = ref<InstanceType<typeof AccountOverview>>();
- const currentEnterpriseId = computed(() => enterpriseStore.getCurrentEnterprise?.enterprise_id);
- const cureentEnterprise = computed(() => enterpriseStore.getCurrentEnterprise);
- const accountInfo = ref<{
- account_book_id: string;
- status: string;
- balance: number;
- }>({
- account_book_id: "",
- status: "",
- balance: 0,
- });
- const authorizeStatus = ref("PENDING");
- const authorizeForm = reactive({
- enterprise_id: "",
- });
- const authorizeRules: FormRules = {
- enterprise_id: [{ required: true, message: "请输入企业ID", trigger: "blur" }],
- };
- const authorizeResult = reactive({
- sign_url: "",
- });
- const createForm = reactive({
- enterprise_id: "",
- account_type: "ALL",
- scene: "B2B_TRANS",
- remark: "",
- });
- const createRules: FormRules = {
- enterprise_id: [{ required: true, message: "请输入企业ID", trigger: "blur" }],
- account_type: [{ required: true, message: "请选择账户类型", trigger: "change" }],
- scene: [{ required: true, message: "请选择场景类型", trigger: "change" }],
- };
- const createResult = reactive({
- enterprise_id: "",
- account_book_id: "",
- });
- const depositForm = reactive({
- enterprise_id: "",
- account_book_id: "",
- amount: 0,
- remark: "",
- });
- const depositRules: FormRules = {
- enterprise_id: [{ required: true, message: "请输入企业ID", trigger: "blur" }],
- account_book_id: [{ required: true, message: "请输入资金专户号", trigger: "blur" }],
- amount: [{ required: true, message: "请输入充值金额", trigger: "blur" }],
- };
- const depositResult = reactive({
- url: "",
- });
- const depositList = ref<any[]>([]);
- const transferForm = reactive({
- enterprise_id: "",
- account_book_id: "",
- amount: 0,
- order_title: "",
- remark: "",
- payee_info: {
- identity_type: "alipay",
- name: "",
- identity: "",
- bankcard_ext_info: {
- account_type: "2",
- inst_name: "",
- inst_province: "",
- inst_city: "",
- inst_branch_name: "",
- bank_code: "",
- },
- },
- });
- const transferRules: FormRules = {
- enterprise_id: [{ required: true, message: "请输入企业ID", trigger: "blur" }],
- account_book_id: [{ required: true, message: "请输入付款资金账户", trigger: "blur" }],
- amount: [{ required: true, message: "请输入转账金额", trigger: "blur" }],
- "payee_info.identity_type": [{ required: true, message: "请选择收款方类型", trigger: "change" }],
- "payee_info.name": [{ required: true, message: "请输入收款方姓名", trigger: "blur" }],
- "payee_info.identity": [{ required: true, message: "请输入收款方账号", trigger: "blur" }],
- };
- const transferList = ref<any[]>([]);
- const transferPage = reactive({
- page_no: 1,
- page_size: 10,
- total: 0,
- });
- const transferSearchForm = reactive({
- out_biz_no: "",
- status: "",
- });
- const transferDetailVisible = ref(false);
- const currentTransferOutBizNo = ref("");
- // 批量转账相关
- const batchTransferVisible = ref(false);
- const batchTransferResultVisible = ref(false);
- const batchTransferLoading = ref(false);
- const showBatchTransferOverlay = ref(false);
- const batchCurrentIndex = ref(0);
- const batchTotalCount = ref(0);
- const batchCurrentPayee = ref("");
- const batchCurrentAmount = ref(0);
- const fileList = ref<any[]>([]);
- const batchTransferData = ref<any[]>([]);
- const batchTransferResults = ref<any[]>([]);
- const batchTransferSuccessCount = ref(0);
- const batchTransferFailCount = ref(0);
- const consumeForm = reactive({
- pay_no: "",
- enterprise_id: "",
- ant_shop_id: "",
- query_options: [] as string[],
- });
- const consumeRules: FormRules = {
- pay_no: [{ required: true, message: "请输入支付宝账单号", trigger: "blur" }],
- };
- const consumeDetail = ref<any>(null);
- function getDepositStatusType(status: string) {
- const map: Record<string, any> = {
- DEALING: "warning",
- SUCCESS: "success",
- FAIL: "danger",
- };
- return map[status] || "info";
- }
- function getTransferStatusType(status: string) {
- const map: Record<string, any> = {
- DEALING: "warning",
- SUCCESS: "success",
- FAIL: "danger",
- REFUND: "warning",
- };
- return map[status] || "info";
- }
- function getPayeeTypeLabel(type: string) {
- const map: Record<string, string> = {
- ALIPAY_ACCOUNT: "支付宝",
- BANK_CARD: "银行卡",
- BOOK: "资金专户",
- };
- return map[type] || type;
- }
- function getStatusLabel(status: string) {
- const map: Record<string, string> = {
- DEALING: "处理中",
- SUCCESS: "成功",
- FAIL: "失败",
- REFUND: "退票",
- };
- return map[status] || status;
- }
- // 批量转账相关计算属性
- const hasBankTransfer = computed(() => {
- return batchTransferData.value.some(item => item.payee_type === "bank");
- });
- const hasInvalidData = computed(() => {
- return batchTransferData.value.some(item => item.status === "invalid");
- });
- // 下载模板
- function downloadTemplate() {
- const workbook = new ExcelJS.Workbook();
- const worksheet = workbook.addWorksheet("批量转账模板");
- // 设置表头
- worksheet.columns = [
- { header: "转账金额", key: "amount", width: 15 },
- { header: "转账标题", key: "order_title", width: 20 },
- { header: "收款方姓名", key: "payee_name", width: 15 },
- { header: "收款方账号类型", key: "payee_type", width: 15 },
- { header: "收款方账号", key: "payee_account", width: 30 },
- { header: "银行账户类型(1:公司账户,2:个人账户)", key: "bank_type", width: 30 },
- { header: "银行名称(公司账户必填)", key: "bank_name", width: 20 },
- { header: "开户省份(非必填)", key: "bank_province", width: 15 },
- { header: "开户城市(非必填)", key: "bank_city", width: 15 },
- { header: "支行名称(非必填)", key: "bank_branch", width: 20 },
- { header: "联行号(非必填)", key: "bank_code", width: 15 },
- { header: "备注(非必填)", key: "remark", width: 20 },
- ];
- // 添加示例数据
- worksheet.addRow({
- amount: 100.00,
- order_title: "测试转账",
- payee_name: "张三",
- payee_type: "alipay",
- payee_account: "zhangsan@example.com",
- remark: "测试"
- });
- worksheet.addRow({
- amount: 200.00,
- order_title: "测试转账",
- payee_name: "李四",
- payee_type: "bank",
- payee_account: "6222021234567890123",
- bank_type: "1",
- bank_name: "中国工商银行",
- bank_province: "北京市",
- bank_city: "北京市",
- bank_branch: "中关村支行",
- bank_code: "102100004534",
- remark: "测试"
- });
- // 生成并下载文件
- workbook.xlsx.writeBuffer().then(buffer => {
- const blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
- const url = URL.createObjectURL(blob);
- const a = document.createElement("a");
- a.href = url;
- a.download = "批量转账模板.xlsx";
- a.click();
- URL.revokeObjectURL(url);
- });
- }
- // 处理文件上传
- async function handleFileChange(file: any) {
- fileList.value = [file.raw];
- await parseExcelFile(file.raw);
- }
- // 解析Excel文件
- async function parseExcelFile(file: File) {
- try {
- const workbook = new ExcelJS.Workbook();
- await workbook.xlsx.load(await file.arrayBuffer());
- const worksheet = workbook.worksheets[0];
-
- const data: any[] = [];
- worksheet.eachRow((row, rowNumber) => {
- if (rowNumber > 1) { // 跳过表头
- const rowData = {
- amount: row.getCell(1).value,
- order_title: row.getCell(2).value,
- payee_name: row.getCell(3).value,
- payee_type: row.getCell(4).value,
- payee_account: row.getCell(5).value,
- bank_type: row.getCell(6).value,
- bank_name: row.getCell(7).value,
- bank_province: row.getCell(8).value,
- bank_city: row.getCell(9).value,
- bank_branch: row.getCell(10).value,
- bank_code: row.getCell(11).value,
- remark: row.getCell(12).value,
- };
- data.push(rowData);
- }
- });
-
- // 验证数据
- batchTransferData.value = data.map(item => validateTransferData(item));
- } catch (error) {
- ElMessage.error("文件解析失败,请检查文件格式");
- console.error(error);
- }
- }
- // 验证转账数据
- function validateTransferData(data: any) {
- const result = {
- ...data,
- status: "valid",
- error_msg: "",
- };
- // 验证金额
- if (!data.amount || typeof data.amount !== "number" || data.amount < 0.02) {
- result.status = "invalid";
- result.error_msg = "转账金额必须大于等于0.02元";
- return result;
- }
- // 验证转账标题
- if (!data.order_title || data.order_title.toString().trim() === "") {
- result.status = "invalid";
- result.error_msg = "转账标题不能为空";
- return result;
- }
- // 验证收款方姓名
- if (!data.payee_name || data.payee_name.toString().trim() === "") {
- result.status = "invalid";
- result.error_msg = "收款方姓名不能为空";
- return result;
- }
- // 验证收款方类型
- if (!data.payee_type || !["alipay", "bank"].includes(data.payee_type)) {
- result.status = "invalid";
- result.error_msg = "收款方类型必须是alipay或bank";
- return result;
- }
- // 验证收款方账号
- if (!data.payee_account || data.payee_account.toString().trim() === "") {
- result.status = "invalid";
- result.error_msg = "收款方账号不能为空";
- return result;
- }
- // 验证银行卡信息
- if (data.payee_type === "bank") {
- if (!data.bank_type || ![1, 2].includes(data.bank_type)) {
- result.status = "invalid";
- result.error_msg = "银行账户类型必须是1或2";
- return result;
- }
- if (data.bank_type === "1" && (!data.bank_name || data.bank_name.toString().trim() === "")) {
- result.status = "invalid";
- result.error_msg = "银行名称不能为空";
- return result;
- }
- }
- return result;
- }
- // 处理批量转账
- async function handleBatchTransfer() {
- const validData = batchTransferData.value.filter(item => item.status === "valid");
- if (validData.length === 0) {
- ElMessage.warning("没有有效的转账数据");
- return;
- }
- ElMessageBox.confirm(
- `确定要批量转账 ${validData.length} 笔交易吗?`,
- "确认操作",
- {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }
- ).then(async () => {
- // 开启遮罩
- showBatchTransferOverlay.value = true;
- batchTransferLoading.value = true;
- batchTotalCount.value = validData.length;
- batchCurrentIndex.value = 0;
- batchTransferResults.value = [];
- batchTransferSuccessCount.value = 0;
- batchTransferFailCount.value = 0;
- try {
- for (let i = 0; i < validData.length; i++) {
- const item = validData[i];
- batchCurrentIndex.value = i + 1;
- batchCurrentPayee.value = item.payee_name;
- batchCurrentAmount.value = item.amount;
- try {
- await AccountAPI.transfer({
- enterprise_id: currentEnterpriseId.value!,
- account_book_id: accountInfo.value.account_book_id,
- amount: item.amount,
- order_title: item.order_title.toString(),
- remark: item.remark?.toString() || "",
- payee_info: {
- identity_type: item.payee_type,
- name: item.payee_name.toString(),
- identity: item.payee_account.toString(),
- bankcard_ext_info:
- item.payee_type === "bank"
- ? {
- account_type: item.bank_type?.toString(),
- inst_name: item.bank_name?.toString(),
- inst_province: item.bank_province?.toString(),
- inst_city: item.bank_city?.toString(),
- inst_branch_name: item.bank_branch?.toString(),
- bank_code: item.bank_code?.toString(),
- }
- : undefined,
- },
- });
- batchTransferResults.value.push({
- amount: item.amount,
- payee_name: item.payee_name,
- status: "success",
- message: "转账成功",
- });
- batchTransferSuccessCount.value++;
- } catch (error: any) {
- batchTransferResults.value.push({
- amount: item.amount,
- payee_name: item.payee_name,
- status: "fail",
- message: error.message || "转账失败",
- });
- batchTransferFailCount.value++;
- }
- }
- // 完成后隐藏遮罩
- showBatchTransferOverlay.value = false;
- // 刷新转账记录
- await handleTransferSearch();
- // 关闭批量转账对话框,显示结果
- batchTransferResultVisible.value = true;
- batchTransferVisible.value = false;
- } catch (error) {
- showBatchTransferOverlay.value = false;
- ElMessage.error("批量转账过程出错");
- } finally {
- batchTransferLoading.value = false;
- }
- });
- }
- // 打开批量转账对话框
- function openBatchTransferDialog() {
- // 重置数据
- resetBatchTransfer();
- // 打开对话框
- batchTransferVisible.value = true;
- }
- // 重置批量转账
- function resetBatchTransfer() {
- batchTransferVisible.value = false;
- batchTransferResultVisible.value = false;
- showBatchTransferOverlay.value = false;
- batchCurrentIndex.value = 0;
- batchTotalCount.value = 0;
- batchCurrentPayee.value = "";
- batchCurrentAmount.value = 0;
- fileList.value = [];
- batchTransferData.value = [];
- batchTransferResults.value = [];
- batchTransferSuccessCount.value = 0;
- batchTransferFailCount.value = 0;
- }
- async function handleAuthorize() {
- // if (!authorizeFormRef.value) return;
- // await authorizeFormRef.value.validate(async (valid) => {
- // if (valid) {
- // authorizeLoading.value = true;
- // try {
- // const res = await AccountAPI.authorizeApply({
- // enterprise_id: authorizeForm.enterprise_id || currentEnterpriseId.value!,
- // });
- // authorizeResult.sign_url = res.data.sign_url || "";
- // } finally {
- // authorizeLoading.value = false;
- // }
- // }
- // });
- try {
- const res = await AccountAPI.authorizeApply({
- enterprise_id: currentEnterpriseId.value!,
- });
- authorizeResult.sign_url = res.data.data?.sign_url || "";
- // 直接打开新窗口跳转
- window.open(authorizeResult.sign_url, "_blank");
- } finally {
- authorizeLoading.value = false;
- }
- }
- function handleAuthorizeReset() {
- authorizeFormRef.value?.resetFields();
- authorizeResult.sign_url = "";
- }
- async function handleCreate() {
- // if (!createFormRef.value) return;
- // await createFormRef.value.validate(async (valid) => {
- // if (valid) {
- // if (authorizeStatus.value !== "AUTHORIZED") {
- // ElMessage.warning("请先完成转账授权签约");
- // return;
- // }
- // createLoading.value = true;
- // try {
- // const res = await AccountAPI.create({
- // enterprise_id: createForm.enterprise_id || currentEnterpriseId.value!,
- // account_type: createForm.account_type,
- // scene: createForm.scene,
- // remark: createForm.remark,
- // });
- // createResult.enterprise_id = res.data.enterprise_id || "";
- // createResult.account_book_id = res.data.account_book_id || "";
- // accountInfo.value.account_book_id = createResult.account_book_id;
- // accountInfo.value.status = "ACTIVE";
- // overviewRef.value?.refresh();
- // } finally {
- // createLoading.value = false;
- // }
- // }
- // });
- try {
- const res = await AccountAPI.create({
- enterprise_id: currentEnterpriseId.value!,
- account_type: "ALL",
- scene: "B2B_TRANS",
- remark: "",
- });
- createResult.enterprise_id = res.data.data.enterprise_id || "";
- createResult.account_book_id = res.data.data.account_book_id || "";
- accountInfo.value.account_book_id = createResult.account_book_id;
- accountInfo.value.status = "AUTHORIZED";
- overviewRef.value?.refresh();
- } finally {
- createLoading.value = false;
- }
- }
- function handleCreateReset() {
- createFormRef.value?.resetFields();
- createResult.enterprise_id = "";
- createResult.account_book_id = "";
- }
- async function handleDeposit() {
- if (!depositFormRef.value) return;
- await depositFormRef.value.validate(async (valid) => {
- if (valid) {
- if (!accountInfo.value.account_book_id) {
- ElMessage.warning("请先开通资金专户");
- return;
- }
- depositLoading.value = true;
- try {
- const res = await AccountAPI.deposit({
- enterprise_id: currentEnterpriseId.value!,
- account_book_id: accountInfo.value.account_book_id,
- amount: depositForm.amount,
- remark: depositForm.remark,
- });
- depositResult.url = res.data.data?.url || "";
- // 直接打开新窗口跳转
- window.open(depositResult.url, "_blank");
- } finally {
- depositLoading.value = false;
- }
- }
- });
- }
- function handleDepositReset() {
- depositFormRef.value?.resetFields();
- depositResult.url = "";
- }
- async function handleTransfer() {
- if (!transferFormRef.value) return;
- await transferFormRef.value.validate(async (valid) => {
- if (valid) {
- if (accountInfo.value.balance <= 0) {
- ElMessage.warning("账户余额不足,请先充值");
- return;
- }
- transferLoading.value = true;
- try {
- await AccountAPI.transfer({
- enterprise_id: currentEnterpriseId.value!,
- account_book_id: accountInfo.value.account_book_id,
- amount: transferForm.amount,
- order_title: transferForm.order_title,
- remark: transferForm.remark,
- payee_info: {
- identity_type: transferForm.payee_info.identity_type,
- name: transferForm.payee_info.name,
- identity: transferForm.payee_info.identity,
- bankcard_ext_info:
- transferForm.payee_info.identity_type === "bank"
- ? transferForm.payee_info.bankcard_ext_info
- : undefined,
- },
- });
- // ElMessage.success("转账申请已提交");
- handleTransferListChange();
- handleTransferReset();
- } finally {
- transferLoading.value = false;
- }
- }
- });
- }
- function handleTransferReset() {
- transferFormRef.value?.resetFields();
- transferForm.payee_info = {
- identity_type: "alipay",
- name: "",
- identity: "",
- bankcard_ext_info: {
- account_type: "2",
- inst_name: "",
- inst_province: "",
- inst_city: "",
- inst_branch_name: "",
- bank_code: "",
- },
- };
- }
- async function handleTransferSearch() {
- transferPage.page_no = 1;
- await fetchTransferList();
- }
- function handleTransferSearchReset() {
- transferSearchForm.out_biz_no = "";
- transferSearchForm.status = "";
- handleTransferSearch();
- }
- async function fetchTransferList() {
- transferListLoading.value = true;
- try {
- const res = await AccountAPI.transferList({
- page_no: transferPage.page_no,
- page_size: transferPage.page_size,
- out_biz_no: transferSearchForm.out_biz_no || undefined,
- status: transferSearchForm.status || undefined,
- });
- transferList.value = res.data.data.items || [];
- transferPage.total = res.data.data.total || 0;
- } finally {
- transferListLoading.value = false;
- }
- }
- function handleTransferListChange() {
- fetchTransferList();
- }
- function handleViewTransferDetail(outBizNo: string) {
- currentTransferOutBizNo.value = outBizNo;
- transferDetailVisible.value = true;
- }
- function handleTransferDetailRefresh() {
- fetchTransferList();
- }
- async function handleConsumeQuery() {
- if (!consumeFormRef.value) return;
- await consumeFormRef.value.validate(async (valid) => {
- if (valid) {
- consumeLoading.value = true;
- try {
- const res = await AccountAPI.consumeDetail({
- pay_no: consumeForm.pay_no,
- enterprise_id: consumeForm.enterprise_id || currentEnterpriseId.value || undefined,
- ant_shop_id: consumeForm.ant_shop_id || undefined,
- query_options: consumeForm.query_options.length > 0 ? consumeForm.query_options : undefined,
- });
- consumeDetail.value = res.data;
- } finally {
- consumeLoading.value = false;
- }
- }
- });
- }
- function handleConsumeReset() {
- consumeFormRef.value?.resetFields();
- consumeDetail.value = null;
- }
- function handleOverviewRefresh(data: any) {
- if (data) {
- accountInfo.value = {
- account_book_id: data.account_book_id || "",
- status: data.status || "",
- balance: data.balance || 0,
- };
- authorizeStatus.value = data.authorize_status || "PENDING";
- }
- }
- async function handleGoTab(tab: string) {
- console.log("goTab => ", tab);
- if (tab === "authorize") {
- await handleAuthorize();
- } else if (tab === "create") {
- await handleCreate();
- } else if (tab === "deposit") {
- activeTab.value = tab;
- } else if (tab === "transfer") {
- activeTab.value = tab;
- }
- }
- onMounted(() => {
- if (currentEnterpriseId.value) {
- authorizeForm.enterprise_id = currentEnterpriseId.value;
- createForm.enterprise_id = currentEnterpriseId.value;
- depositForm.enterprise_id = currentEnterpriseId.value;
- transferForm.enterprise_id = currentEnterpriseId.value;
- consumeForm.enterprise_id = currentEnterpriseId.value;
- }
- });
- watch(activeTab, async (newValue) => {
- if (newValue === "transfer") {
- await handleTransferSearch();
- }
- })
- // watch(batchTransferVisible, (newValue) => {
- // if (!newValue) {
- // resetBatchTransfer();
- // }
- // })
- onMounted(async() => {
- pageLoading.value = true;
- try {
- await overviewRef.value?.refresh();
- } finally {
- pageLoading.value = false;
- }
- });
- </script>
- <style lang="scss" scoped>
- .account-tabs {
- height: 100%;
- :deep(.el-tabs__content) {
- height: calc(100% - 40px);
- overflow-y: auto;
- }
- }
- .tab-content {
- padding: 0;
- }
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .mt-4 {
- margin-top: 16px;
- }
- .ml-2 {
- margin-left: 8px;
- }
- .mb-4 {
- margin-bottom: 16px;
- }
- .flex {
- display: flex;
- }
- .justify-end {
- justify-content: flex-end;
- }
- .authorize-result,
- .create-result,
- .deposit-result {
- margin-top: 20px;
- }
- .batch-transfer-container {
- position: relative;
- &.has-overlay {
- pointer-events: none;
- }
- }
- .batch-transfer-overlay {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(255, 255, 255, 0.95);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 10;
- border-radius: 8px;
- .overlay-content {
- text-align: center;
- padding: 40px;
- h3 {
- margin: 20px 0;
- color: #303133;
- }
- p {
- margin: 15px 0;
- color: #606266;
- }
- .result-summary {
- display: flex;
- gap: 15px;
- justify-content: center;
- margin-top: 20px;
- }
- }
- }
- </style>
|