feat: 优化估值记录分页及跳转功能,重构企业转让凭证上传与开票信息管理,并调整开票管理为抬头管理

This commit is contained in:
Wei_佳 2025-11-21 17:55:03 +08:00
parent 1b56856995
commit a148b94dff
7 changed files with 461 additions and 556 deletions

View File

@ -49,7 +49,7 @@ export const basicRoutes = [
path: 'invoice',
component: () => import('@/views/user-center/components/InvoiceManagement.vue'),
meta: {
title: '开票管理',
title: '抬头管理',
},
},
],

View File

@ -1087,10 +1087,11 @@ const previousStep = () => {
currentStep.value --
}
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { unref } from 'vue'
const router = useRouter()
const route = useRoute()
const navToLogin = () => {
userStore.logout()
@ -1191,10 +1192,12 @@ const submit = () => {
const getHistoryList = () => {
const params = {
page: 1,
size: 99
page_size: 99
};
api.getHistoryList(params).then(res=>{
historyList.value = res.data
return api.getHistoryList(params).then(res=>{
const list = res?.data?.items ?? res?.data?.results ?? res?.results ?? []
historyList.value = Array.isArray(list) ? list : []
return res
})
}
const selectedObj = ref({
@ -1327,6 +1330,14 @@ onMounted(async () => {
page_size: 99
};
await getHistoryList()
if (route.query.id) {
const targetId = Number(route.query.id)
const targetItem = historyList.value.find(item => item.id === targetId)
if (targetItem) {
selectTimeBox(targetItem)
}
}
// 使await
const res = await api.getIndustryList(params);

View File

@ -81,63 +81,69 @@
</div>
</div>
<!-- 第二步上传凭证 -->
<!-- 第二步上传凭证 -->
<div v-if="currentStep === 2" class="step-content">
<div class="form-container">
<div class="form-group">
<div class="form-label required">上传支付凭证</div>
<div class="upload-box" @click="triggerFileInput">
<input
ref="fileInput"
type="file"
accept="image/*"
style="display: none"
@change="handleFileChange"
<n-form
ref="formRef"
:model="formModel"
label-placement="top"
require-mark-placement="left"
class="custom-form"
>
<n-form-item label="上传支付凭证" required>
<n-upload
v-model:file-list="fileList"
list-type="image-card"
:max="1"
accept="image/png,image/jpeg,image/jpg"
:custom-request="customRequest"
@change="handleUploadChange"
>
<div class="upload-trigger">
<div class="upload-icon">+</div>
<div class="upload-text">添加图片</div>
</div>
</n-upload>
<template #feedback>
<div class="form-tip">支持jpgpngjpeg格式大小不超过5M</div>
</template>
</n-form-item>
<n-form-item label="开票抬头" required>
<div class="select-wrapper">
<n-select
v-model:value="formModel.invoiceHeader"
:options="invoiceHeaderOptions"
placeholder="请选择开票抬头"
class="flex-1"
/>
<div class="add-header-link" @click="handleAddHeader">+ 添加抬头</div>
</div>
</n-form-item>
<n-form-item label="开票类型" required>
<n-select
v-model:value="formModel.invoiceType"
:options="invoiceTypeOptions"
placeholder="请选择开票类型"
/>
<div v-if="!uploadedFile" class="upload-placeholder">
<div class="upload-icon">+</div>
<div class="upload-text">点击上传</div>
</div>
<div v-else class="upload-preview">
<img :src="uploadedFileUrl" alt="支付凭证" />
<div class="upload-remove" @click.stop="removeFile">×</div>
</div>
</n-form-item>
<div class="btn-container">
<n-button
type="primary"
class="submit-btn"
:disabled="!isFormValid"
@click="handleUploadSubmit"
color="#A30113"
style="width: 200px; height: 40px;"
>
确认上传
</n-button>
</div>
<div class="form-tip">支持jpgpngjpeg格式大小不超过5M</div>
</div>
<div class="form-group">
<div class="form-label required">开票抬头</div>
<div class="select-wrapper">
<select v-model="selectedInvoiceHeader" class="custom-select">
<option value="" disabled selected>请选择开票抬头</option>
<option v-for="opt in invoiceHeaderOptions" :key="opt.value" :value="opt.value">
{{ opt.label }}
</option>
</select>
<div class="add-header-link" @click="handleAddHeader">+ 添加抬头</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">开票类型</div>
<select v-model="selectedInvoiceType" class="custom-select">
<option value="" disabled selected>请选择开票类型</option>
<option v-for="opt in invoiceTypeOptions" :key="opt.value" :value="opt.value">
{{ opt.label }}
</option>
</select>
</div>
<div class="btn-container">
<button
class="primary-btn"
:disabled="!uploadedFile || !selectedInvoiceHeader || !selectedInvoiceType"
@click="handleUploadSubmit"
>
确认上传
</button>
</div>
</n-form>
</div>
</div>
@ -158,17 +164,13 @@
</div>
</div>
<!-- 引入抬头管理弹窗 -->
<InvoiceModal
v-model:show="showInvoiceModal"
@submit="handleInvoiceModalSubmit"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import InvoiceModal from './InvoiceModal.vue'
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
const emit = defineEmits(['return-home'])
@ -181,9 +183,8 @@ const uploadedFile = ref(null)
const uploadedFileUrl = ref('')
//
const selectedInvoiceHeader = ref('')
const selectedInvoiceType = ref('')
const showInvoiceModal = ref(false)
const router = useRouter()
//
const invoiceHeaderOptions = ref([
@ -204,60 +205,51 @@ function handleNextStep() {
}
}
//
function triggerFileInput() {
fileInput.value?.click()
}
//
function handleFileChange(event) {
const file = event.target.files?.[0]
if (file) {
//
if (!file.type.startsWith('image/')) {
$message.warning('请上传图片格式的文件')
return
}
uploadedFile.value = file
uploadedFileUrl.value = URL.createObjectURL(file)
}
}
//
function removeFile() {
uploadedFile.value = null
uploadedFileUrl.value = ''
if (fileInput.value) {
fileInput.value.value = ''
}
}
//
function handleAddHeader() {
showInvoiceModal.value = true
router.push({ path: '/user-center/invoice', query: { action: 'create' } })
}
//
function handleInvoiceModalSubmit(data) {
//
const newOption = { label: data.name, value: 'header_' + Date.now() }
invoiceHeaderOptions.value.push(newOption)
selectedInvoiceHeader.value = newOption.value
showInvoiceModal.value = false
$message.success('添加抬头成功')
//
const formModel = reactive({
invoiceHeader: null,
invoiceType: null
})
const fileList = ref([])
const message = useMessage()
//
const isFormValid = computed(() => {
return fileList.value.length > 0 && formModel.invoiceHeader && formModel.invoiceType
})
//
const customRequest = ({ file, onFinish }) => {
setTimeout(() => {
onFinish()
}, 500)
}
//
function handleUploadChange({ fileList: newFileList }) {
fileList.value = newFileList
if (newFileList.length > 0) {
uploadedFile.value = newFileList[0].file
} else {
uploadedFile.value = null
}
}
//
function handleUploadSubmit() {
if (!uploadedFile.value || !selectedInvoiceHeader.value || !selectedInvoiceType.value) {
$message.warning('请完成所有必填项')
if (!isFormValid.value) {
message.warning('请完成所有必填项')
return
}
// API
//
$message.success('上传成功')
message.success('上传成功')
currentStep.value = 3
}
@ -408,83 +400,7 @@ defineExpose({
margin: 0 auto;
}
.form-group {
margin-bottom: 24px;
}
.form-label {
font-size: 14px;
color: #606266;
margin-bottom: 8px;
}
.form-label.required::before {
content: '*';
color: #F56C6C;
margin-right: 4px;
}
.upload-box {
width: 120px;
height: 120px;
border: 1px dashed #DCDFE6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: border-color 0.3s;
background: #F5F7FA;
position: relative;
overflow: hidden;
}
.upload-box:hover {
border-color: #A30113;
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
color: #909399;
}
.upload-icon {
font-size: 24px;
font-weight: 300;
}
.upload-text {
font-size: 12px;
}
.upload-preview {
width: 100%;
height: 100%;
}
.upload-preview img {
width: 100%;
height: 100%;
object-fit: cover;
}
.upload-remove {
position: absolute;
top: 0;
right: 0;
width: 20px;
height: 20px;
background: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
cursor: pointer;
}
.form-tip {
font-size: 12px;
@ -496,23 +412,14 @@ defineExpose({
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
.custom-select {
.flex-1 {
flex: 1;
height: 40px;
border: 1px solid #DCDFE6;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
color: #606266;
outline: none;
background: white;
}
.custom-select:focus {
border-color: #A30113;
}
.add-header-link {
font-size: 14px;
@ -572,4 +479,23 @@ defineExpose({
background: #fab6b6;
cursor: not-allowed;
}
.upload-trigger {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #909399;
}
.upload-icon {
font-size: 24px;
margin-bottom: 8px;
}
.upload-text {
font-size: 12px;
}
</style>

View File

@ -22,18 +22,107 @@
/>
</div>
<InvoiceModal
<!-- 添加/编辑抬头弹窗 -->
<n-modal
v-model:show="showModal"
:edit-data="currentInvoice"
@submit="handleModalSubmit"
/>
:mask-closable="false"
preset="card"
:title="currentInvoice ? '编辑抬头' : '添加抬头'"
class="invoice-modal"
:style="{ width: '600px' }"
:bordered="false"
:segmented="{ content: true }"
>
<n-form
ref="formRef"
:model="formData"
:rules="formRules"
label-placement="top"
require-mark-placement="left"
:show-feedback="true"
>
<n-grid :cols="2" :x-gap="16">
<!-- 公司名称 -->
<n-form-item-gi :span="1" path="companyName" label="公司名称">
<n-input
v-model:value="formData.companyName"
placeholder="请输入公司名称"
clearable
/>
</n-form-item-gi>
<!-- 公司税号 -->
<n-form-item-gi :span="1" path="taxNumber" label="公司税号">
<n-input
v-model:value="formData.taxNumber"
placeholder="请输入公司税号"
clearable
/>
</n-form-item-gi>
<!-- 注册地址 -->
<n-form-item-gi :span="2" path="registeredAddress" label="注册地址">
<n-input
v-model:value="formData.registeredAddress"
placeholder="请输入注册地址"
clearable
/>
</n-form-item-gi>
<!-- 注册电话 -->
<n-form-item-gi :span="2" path="registeredPhone" label="注册电话">
<n-input
v-model:value="formData.registeredPhone"
placeholder="请输入注册电话"
clearable
/>
</n-form-item-gi>
<!-- 开户银行 -->
<n-form-item-gi :span="1" path="bankName" label="开户银行">
<n-input
v-model:value="formData.bankName"
placeholder="请输入开户银行"
clearable
/>
</n-form-item-gi>
<!-- 银行账号 -->
<n-form-item-gi :span="1" path="bankAccount" label="银行账号">
<n-input
v-model:value="formData.bankAccount"
placeholder="请输入银行账号"
clearable
/>
</n-form-item-gi>
<!-- 电子邮箱 -->
<n-form-item-gi :span="2" path="email" label="电子邮箱">
<n-input
v-model:value="formData.email"
placeholder="请输入邮箱"
clearable
/>
<template #feedback>
<span class="email-hint">此邮箱用于接收发票请填写正确</span>
</template>
</n-form-item-gi>
</n-grid>
</n-form>
<template #footer>
<div class="modal-footer">
<n-button class="cancel-btn" @click="handleCancel">取消</n-button>
<n-button class="save-btn" @click="handleSave">保存</n-button>
</div>
</template>
</n-modal>
</div>
</template>
<script setup>
import { h, ref } from 'vue'
import { NButton, NDataTable, NSpace } from 'naive-ui'
import InvoiceModal from './InvoiceModal.vue'
import { h, ref, watch } from 'vue'
import { NButton, NDataTable, NSpace, NModal, NForm, NFormItemGi, NGrid, NInput } from 'naive-ui'
const props = defineProps({
invoiceList: {
@ -46,6 +135,57 @@ const emit = defineEmits(['add-invoice', 'delete-invoice', 'update-invoice'])
const showModal = ref(false)
const currentInvoice = ref(null)
const formRef = ref(null)
//
const formData = ref({
companyName: '',
taxNumber: '',
registeredAddress: '',
registeredPhone: '',
bankName: '',
bankAccount: '',
email: ''
})
//
const formRules = {
companyName: [
{ required: true, message: '请输入公司名称', trigger: 'blur' }
],
taxNumber: [
{ required: true, message: '请输入公司税号', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入电子邮箱', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: '请输入正确的邮箱格式',
trigger: 'blur'
}
]
}
// ,
watch(showModal, (newVal) => {
if (newVal) {
if (currentInvoice.value) {
// ,
formData.value = { ...currentInvoice.value }
} else {
// ,
formData.value = {
companyName: '',
taxNumber: '',
registeredAddress: '',
registeredPhone: '',
bankName: '',
bankAccount: '',
email: ''
}
}
}
})
//
function handleAddInvoice() {
@ -65,6 +205,21 @@ function handleDeleteInvoice(invoice) {
emit('delete-invoice', invoice)
}
//
function handleCancel() {
showModal.value = false
formRef.value?.restoreValidation()
}
//
function handleSave() {
formRef.value?.validate((errors) => {
if (!errors) {
handleModalSubmit(formData.value)
}
})
}
//
function handleModalSubmit(data) {
if (currentInvoice.value) {
@ -83,7 +238,7 @@ const columns = [
ellipsis: true,
align: 'center',
titleAlign: 'center',
render: (row) => row.name || '-'
render: (row) => row.name || row.companyName || '-'
},
{
title: '税号',
@ -91,7 +246,7 @@ const columns = [
minWidth: 200,
align: 'center',
titleAlign: 'center',
render: (row) => row.taxId || '123456789012345678'
render: (row) => row.taxId || row.taxNumber || '123456789012345678'
},
{
title: '操作',
@ -131,7 +286,7 @@ const columns = [
}
]
const rowKey = (row) => row.id ?? row.name ?? row.taxId
const rowKey = (row) => row.id ?? row.name ?? row.companyName ?? row.taxId ?? row.taxNumber
</script>
<style scoped>
@ -194,4 +349,85 @@ const rowKey = (row) => row.id ?? row.name ?? row.taxId
.table-container {
width: 100%;
}
/* 弹窗样式 */
:deep(.invoice-modal) {
border-radius: 8px;
}
:deep(.invoice-modal .n-card-header) {
padding: 20px 24px;
border-bottom: 1px solid #f0f0f0;
font-size: 16px;
font-weight: 600;
color: #303133;
}
:deep(.invoice-modal .n-card__content) {
padding: 24px;
}
:deep(.n-form-item-label) {
font-size: 14px;
color: #303133;
font-weight: 500;
margin-bottom: 8px;
}
:deep(.n-form-item-label__asterisk) {
color: #A30113;
}
:deep(.n-input) {
border-radius: 4px;
}
:deep(.n-input__input-el::placeholder) {
color: #C0C4CC;
}
.email-hint {
font-size: 12px;
color: #A30113;
margin-top: 4px;
display: inline-block;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
padding-top: 16px;
}
.cancel-btn {
padding: 8px 24px;
border: 1px solid #DCDFE6;
background: white;
color: #606266;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
}
.cancel-btn:hover {
border-color: #C0C4CC;
background: #F5F7FA;
}
.save-btn {
padding: 8px 24px;
background: #A30113;
color: white;
border: none;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: background 0.3s;
}
.save-btn:hover {
background: #880C22;
}
</style>

View File

@ -1,275 +0,0 @@
<template>
<div v-if="show" class="modal-overlay" @click="handleClose">
<div class="modal-content" @click.stop>
<div class="modal-header">
<div class="header-title">{{ editData ? '编辑抬头' : '添加抬头' }}</div>
<div class="close-btn" @click="handleClose">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18M6 6L18 18" stroke="#909399" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
</div>
<div class="modal-body">
<div class="form-item">
<div class="label required">公司名称</div>
<input
v-model="formData.name"
type="text"
placeholder="请输入公司名称"
class="custom-input"
/>
</div>
<div class="form-item">
<div class="label required">税号</div>
<input
v-model="formData.taxId"
type="text"
placeholder="请输入纳税人识别号"
class="custom-input"
/>
</div>
<div class="form-item">
<div class="label">注册地址</div>
<input
v-model="formData.address"
type="text"
placeholder="请输入注册地址"
class="custom-input"
/>
</div>
<div class="form-item">
<div class="label">注册电话</div>
<input
v-model="formData.phone"
type="text"
placeholder="请输入注册电话"
class="custom-input"
/>
</div>
<div class="form-item">
<div class="label">开户银行</div>
<input
v-model="formData.bank"
type="text"
placeholder="请输入开户银行"
class="custom-input"
/>
</div>
<div class="form-item">
<div class="label">银行账号</div>
<input
v-model="formData.account"
type="text"
placeholder="请输入银行账号"
class="custom-input"
/>
</div>
<div class="form-note">
* 电子发票PDF和纸质发票具有同等法律效力可支持报销入账
</div>
</div>
<div class="modal-footer">
<button class="btn cancel" @click="handleClose">取消</button>
<button class="btn submit" @click="handleSubmit">保存</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
show: Boolean,
editData: {
type: Object,
default: null
}
})
const emit = defineEmits(['update:show', 'submit'])
const formData = ref({
name: '',
taxId: '',
address: '',
phone: '',
bank: '',
account: ''
})
watch(() => props.show, (newVal) => {
if (newVal) {
if (props.editData) {
formData.value = { ...props.editData }
} else {
formData.value = {
name: '',
taxId: '',
address: '',
phone: '',
bank: '',
account: ''
}
}
}
})
function handleClose() {
emit('update:show', false)
}
function handleSubmit() {
if (!formData.value.name || !formData.value.taxId) {
$message.warning('请填写必填项')
return
}
emit('submit', formData.value)
}
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-content {
background: white;
border-radius: 8px;
width: 600px;
max-width: 90%;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 24px;
border-bottom: 1px solid #EBEEF5;
}
.header-title {
font-size: 18px;
font-weight: 600;
color: #303133;
}
.close-btn {
cursor: pointer;
color: #909399;
transition: color 0.3s;
}
.close-btn:hover {
color: #606266;
}
.modal-body {
padding: 24px;
display: flex;
flex-direction: column;
gap: 20px;
}
.form-item {
display: flex;
flex-direction: column;
gap: 8px;
}
.label {
font-size: 14px;
color: #606266;
}
.label.required::before {
content: '*';
color: #F56C6C;
margin-right: 4px;
}
.custom-input {
height: 40px;
padding: 0 12px;
border: 1px solid #DCDFE6;
border-radius: 4px;
font-size: 14px;
color: #606266;
outline: none;
transition: border-color 0.3s;
}
.custom-input:focus {
border-color: #A30113;
}
.custom-input::placeholder {
color: #C0C4CC;
}
.form-note {
font-size: 12px;
color: #A30113;
margin-top: 4px;
}
.modal-footer {
padding: 20px 24px;
border-top: 1px solid #EBEEF5;
display: flex;
justify-content: flex-end;
gap: 12px;
}
.btn {
padding: 8px 24px;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
border: 1px solid;
}
.btn.cancel {
background: white;
border-color: #DCDFE6;
color: #606266;
}
.btn.cancel:hover {
color: #A30113;
border-color: #fde2e2;
background-color: #fef0f0;
}
.btn.submit {
background: #A30113;
border-color: #A30113;
color: white;
}
.btn.submit:hover {
background: #880C22;
border-color: #880C22;
}
</style>

View File

@ -15,7 +15,8 @@
:columns="columns"
:data="tableData"
:row-key="rowKey"
:pagination="false"
:pagination="pagination"
remote
striped
size="medium"
/>
@ -23,7 +24,8 @@
</template>
<script setup>
import { h, onMounted, ref } from 'vue'
import { h, onMounted, ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { NButton, NSpace } from 'naive-ui'
import api from '@/api'
@ -34,6 +36,10 @@ const props = defineProps({
},
})
const router = useRouter()
const loading = ref(false)
const tableData = ref([...props.assetList])
@ -50,29 +56,72 @@ function formatDate(dateStr) {
return `${dateStr.slice(0, 10)} ${dateStr.slice(11, 16)}`
}
const pagination = reactive({
page: 1,
pageSize: 10,
itemCount: 0,
showSizePicker: true,
pageSizes: [10, 20, 50],
prefix: ({ itemCount }) => `${itemCount}`,
onChange: (page) => {
pagination.page = page
fetchHistory()
},
onUpdatePageSize: (pageSize) => {
pagination.pageSize = pageSize
pagination.page = 1
fetchHistory()
}
})
const columns = [
{
title: '序号',
key: 'index',
width: 80,
align: 'center',
titleAlign: 'center',
render: (_, index) => (pagination.page - 1) * pagination.pageSize + index + 1
},
{
title: '资产名称',
key: 'asset_name',
minWidth: 200,
ellipsis: true,
render: (row) => row.asset_name || row.name || '未知资产',
align: 'center',
titleAlign: 'center',
render: (row) => h(
'div',
{
class: 'asset-name-link',
onClick: () => {
router.push({
path: '/pages',
query: { id: row.id }
})
}
},
row.asset_name || row.name || '未知资产'
),
},
{
title: '评估时间',
key: 'created_at',
minWidth: 180,
align: 'center',
titleAlign: 'center',
render: (row) => formatDate(row.created_at),
},
{
title: '操作',
key: 'actions',
align: 'right',
align: 'center',
titleAlign: 'center',
width: 220,
render: (row) =>
h(
NSpace,
{ size: 8 },
{ size: 8, justify: 'center' },
{
default: () => [
h(
@ -81,7 +130,10 @@ const columns = [
text: true,
type: 'primary',
size: 'small',
onClick: () => handleDownloadReport(row),
onClick: (e) => {
e.stopPropagation()
handleDownloadReport(row)
},
},
{ default: () => '下载报告' }
),
@ -91,7 +143,10 @@ const columns = [
text: true,
type: 'primary',
size: 'small',
onClick: () => handleDownloadCertificate(row),
onClick: (e) => {
e.stopPropagation()
handleDownloadCertificate(row)
},
},
{ default: () => '下载证书' }
),
@ -106,9 +161,13 @@ const rowKey = (row) => row.id ?? row.asset_name ?? row.name
async function fetchHistory() {
loading.value = true
try {
const res = await api.getHistoryList({ page: 1, page_size: 50 })
const list = res?.data?.results ?? res?.data ?? res?.results ?? []
const res = await api.getHistoryList({
page: pagination.page,
page_size: pagination.pageSize
})
const list = res?.data?.items ?? res?.data?.results ?? res?.results ?? []
tableData.value = Array.isArray(list) ? list : []
pagination.itemCount = res?.data?.total ?? res?.total ?? 0
} catch (error) {
console.error('加载估值记录失败:', error)
tableData.value = props.assetList
@ -155,4 +214,16 @@ onMounted(fetchHistory)
.empty-block {
padding: 24px 0;
}
:deep(.asset-name-link) {
cursor: pointer;
color: #A30113;
font-weight: 500;
transition: all 0.3s;
}
:deep(.asset-name-link:hover) {
opacity: 0.8;
text-decoration: underline;
}
</style>

View File

@ -72,79 +72,15 @@ const menuList = ref([
{
id: 'history',
label: '估值记录',
icon: () => h('svg', {
width: 20,
height: 20,
viewBox: '0 0 24 24',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg'
}, [
h('path', {
d: 'M12 8V12L15 15',
stroke: 'currentColor',
'stroke-width': 2,
'stroke-linecap': 'round'
}),
h('circle', {
cx: 12,
cy: 12,
r: 9,
stroke: 'currentColor',
'stroke-width': 2
})
])
},
{
id: 'transfer',
label: '对公转账',
icon: () => h('svg', {
width: 20,
height: 20,
viewBox: '0 0 24 24',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg'
}, [
h('path', {
d: 'M12 2V6M12 18V22M6 12H2M22 12H18',
stroke: 'currentColor',
'stroke-width': 2,
'stroke-linecap': 'round'
}),
h('circle', {
cx: 12,
cy: 12,
r: 4,
stroke: 'currentColor',
'stroke-width': 2
})
])
},
{
id: 'invoice',
label: '开票管理',
icon: () => h('svg', {
width: 20,
height: 20,
viewBox: '0 0 24 24',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg'
}, [
h('rect', {
x: 3,
y: 3,
width: 18,
height: 18,
rx: 2,
stroke: 'currentColor',
'stroke-width': 2
}),
h('path', {
d: 'M8 12H16M8 16H13',
stroke: 'currentColor',
'stroke-width': 2,
'stroke-linecap': 'round'
})
])
label: '抬头管理',
}
])