feat: 对公转账上传凭证

This commit is contained in:
hhm 2025-11-25 12:14:10 +08:00
parent f6243a66a0
commit de8c4e9cab
3 changed files with 140 additions and 61 deletions

View File

@ -82,4 +82,5 @@ export default {
addInvoiceHeaders: (data = {}) => request.post('/app-invoices/headers', data),
updateInvoiceHeaders: (data = {}) => request.put(`/app-invoices/headers/${data.id}`, data),
deleteInvoiceHeaders: (id) => request.delete(`/app-invoices/headers/${id}`),
createWithReceipt: (data = {}) => request.post('/app-invoices/create-with-receipt', data),
}

View File

@ -11,29 +11,79 @@
<div class="step" :class="{ active: currentStep >= 1 }">
<div class="step-icon">
<span v-if="currentStep === 1">1</span>
<svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 6L9 17L4 12" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<svg
v-else
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 6L9 17L4 12"
stroke="white"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="step-label">对公汇款</div>
</div>
<div class="step-line">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 18L15 12L9 6" stroke="#C0C4CC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18L15 12L9 6"
stroke="#C0C4CC"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="step" :class="{ active: currentStep >= 2 }">
<div class="step-icon">
<span v-if="currentStep <= 2">2</span>
<svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 6L9 17L4 12" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<svg
v-else
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 6L9 17L4 12"
stroke="white"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="step-label">上传凭证</div>
</div>
<div class="step-line">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 18L15 12L9 6" stroke="#C0C4CC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 18L15 12L9 6"
stroke="#C0C4CC"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="step" :class="{ active: currentStep >= 3 }">
@ -47,7 +97,7 @@
<div class="info-card">
<div class="info-title">评估收费标准<span class="highlight">6000/</span></div>
<div class="info-subtitle">请汇款至以下账户</div>
<div class="info-grid">
<div class="info-item">
<span class="label">公司名称</span>
@ -75,7 +125,7 @@
</div>
</div>
</div>
<div class="btn-container">
<button class="primary-btn" @click="handleNextStep">下一步</button>
</div>
@ -94,16 +144,17 @@
>
<n-form-item label="上传支付凭证" required>
<n-upload
:action="actionUrl"
v-model:file-list="fileList"
list-type="image-card"
:max="1"
accept="image/png,image/jpeg,image/jpg"
:custom-request="customRequest"
@change="handleUploadChange"
@finish="handleUploadFinish"
@remove="deleteUpload"
>
<div class="upload-trigger">
<div class="upload-icon">+</div>
<div class="upload-text">添加图片</div>
<div>
<img style="width: 24px; height: 24px" src="@/assets/images/upload.png" alt="" />
<p style="font-size: 12px">添加图片</p>
</div>
</n-upload>
<template #feedback>
@ -138,7 +189,7 @@
:disabled="!isFormValid"
@click="handleUploadSubmit"
color="#A30113"
style="width: 200px; height: 40px;"
style="width: 200px; height: 40px"
>
确认上传
</n-button>
@ -150,20 +201,31 @@
<!-- 第三步等待到账 -->
<div v-if="currentStep === 3" class="step-content success-content">
<div class="success-icon">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="12" fill="#67C23A"/>
<path d="M17 8L10 15L7 12" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<svg
width="64"
height="64"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="12" cy="12" r="12" fill="#67C23A" />
<path
d="M17 8L10 15L7 12"
stroke="white"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="success-title">上传成功</div>
<div class="success-desc">预计1-3个工作日内到账请耐心等待</div>
<div class="btn-container">
<button class="primary-btn" @click="handleReturnHome">返回首页</button>
</div>
</div>
</div>
</div>
</template>
@ -172,7 +234,23 @@ import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
const emit = defineEmits(['return-home'])
const props = defineProps({
invoiceList: {
type: Array,
default: () => [],
},
})
const invoiceHeaderOptions = computed(() => {
return props.invoiceList.map((item) => ({
label: item.company_name || item.name,
value: item.id,
}))
})
const emit = defineEmits(['return-home', 'upload-submit'])
const actionUrl = 'https://value.cdcee.net/api/v1/upload/image'
//
const currentStep = ref(1)
@ -187,15 +265,15 @@ const uploadedFileUrl = ref('')
const router = useRouter()
//
const invoiceHeaderOptions = ref([
{ label: '上海某某科技有限公司', value: 'header1' },
{ label: '北京某某文化有限公司', value: 'header2' }
])
// const invoiceHeaderOptions = ref([
// { label: '', value: 'header1' },
// { label: '', value: 'header2' }
// ])
//
const invoiceTypeOptions = ref([
{ label: '普通发票', value: 'normal' },
{ label: '增值税专用发票', value: 'vat' }
{ label: '增值税专用发票', value: 'special' },
])
//
@ -205,8 +283,6 @@ function handleNextStep() {
}
}
//
function handleAddHeader() {
router.push({ path: '/user-center/invoice', query: { action: 'create' } })
@ -215,7 +291,7 @@ function handleAddHeader() {
//
const formModel = reactive({
invoiceHeader: null,
invoiceType: null
invoiceType: null,
})
const fileList = ref([])
const message = useMessage()
@ -225,21 +301,12 @@ const isFormValid = computed(() => {
return fileList.value.length > 0 && formModel.invoiceHeader && formModel.invoiceType
})
//
const customRequest = ({ file, onFinish }) => {
setTimeout(() => {
onFinish()
}, 500)
const handleUploadFinish = (file) => {
let url = JSON.parse(file.event.target.response)
uploadedFile.value = url.url
}
//
function handleUploadChange({ fileList: newFileList }) {
fileList.value = newFileList
if (newFileList.length > 0) {
uploadedFile.value = newFileList[0].file
} else {
uploadedFile.value = null
}
const deleteUpload = () => {
uploadedFile.value = ''
}
//
@ -248,8 +315,13 @@ function handleUploadSubmit() {
message.warning('请完成所有必填项')
return
}
message.success('上传成功')
console.log('formModel====', formModel)
emit('upload-submit', {
header_id: formModel.invoiceHeader,
ticket_type: 'electronic',
invoice_type: formModel.invoiceType,
receipt_url: uploadedFile.value,
})
currentStep.value = 3
}
@ -264,7 +336,7 @@ function resetStep() {
}
defineExpose({
resetStep
resetStep,
})
</script>
@ -286,7 +358,7 @@ defineExpose({
.title-bar {
width: 4px;
height: 16px;
background: #A30113;
background: #a30113;
border-radius: 2px;
}
@ -320,7 +392,7 @@ defineExpose({
width: 24px;
height: 24px;
border-radius: 50%;
background: #C0C4CC;
background: #c0c4cc;
color: white;
display: flex;
align-items: center;
@ -330,7 +402,7 @@ defineExpose({
}
.step.active .step-icon {
background: #A30113;
background: #a30113;
}
.step-label {
@ -346,12 +418,12 @@ defineExpose({
.step-line {
display: flex;
align-items: center;
color: #C0C4CC;
color: #c0c4cc;
}
/* 第一步内容 */
.info-card {
background: #F9FAFC;
background: #f9fafc;
border-radius: 8px;
padding: 40px;
margin-bottom: 40px;
@ -364,7 +436,7 @@ defineExpose({
}
.info-title .highlight {
color: #A30113;
color: #a30113;
font-weight: 600;
}
@ -400,11 +472,9 @@ defineExpose({
margin: 0 auto;
}
.form-tip {
font-size: 12px;
color: #C0C4CC;
color: #c0c4cc;
margin-top: 8px;
}
@ -419,11 +489,9 @@ defineExpose({
flex: 1;
}
.add-header-link {
font-size: 14px;
color: #A30113;
color: #a30113;
cursor: pointer;
white-space: nowrap;
}
@ -462,7 +530,7 @@ defineExpose({
.primary-btn {
width: 200px;
height: 40px;
background: #A30113;
background: #a30113;
color: white;
border: none;
border-radius: 4px;
@ -472,7 +540,7 @@ defineExpose({
}
.primary-btn:hover {
background: #880C22;
background: #880c22;
}
.primary-btn:disabled {

View File

@ -32,6 +32,7 @@
@add-invoice="addInvoice"
@update-invoice="updateInvoice"
@delete-invoice="deleteInvoice"
@upload-submit="uploadSubmit"
/>
</div>
</div>
@ -156,6 +157,15 @@ async function deleteInvoice(data) {
console.error('删除发票抬头失败:', error)
}
}
//
async function uploadSubmit(data) {
try {
console.log('上传对公转账凭证===', data)
await api.createWithReceipt(data)
} catch (error) {
console.error('上传对公转账凭证失败:', error)
}
}
onMounted(() => {
loadData()