You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

916 lines
23 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page-container">
<view class="content">
<!-- 查询区域 -->
<view class="search-section">
<view class="search-card">
<view class="input-row">
<tn-input v-model="searchValue" :placeholder="placeholderText" border height="80rpx"
class="search-input">
</tn-input>
<tn-button type="primary" @click="handleSearch" :loading="loading" class="search-btn">
查询
</tn-button>
<tn-button width="80px" height="32px" :plain="true" text-color="#0099ff" @click="backToIndex">
<uni-icons type="arrow-left" size="18" color="#0099ff" style="margin-right: 5px;"></uni-icons>返回
</tn-button>
</view>
</view>
</view>
<!-- 纳税人基础信息 -->
<view v-if="taxPayerInfo" class="info-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">纳税人基础信息</text>
<view class="status-badges">
<view class="status-badge" :class="getTaxStatusClass(taxPayerInfo.taxStatus)">
{{ taxPayerInfo.taxStatus }}
</view>
<view class="status-badge" :class="getCreditLevelClass(taxPayerInfo.creditLevel)">
信用{{ taxPayerInfo.creditLevel }}
</view>
</view>
</view>
<view class="info-grid">
<view class="info-group">
<view class="group-title">登记信息</view>
<view class="info-row">
<text class="info-label">纳税人名称:</text>
<text class="info-value">{{ taxPayerInfo.name }}</text>
</view>
<view class="info-row">
<text class="info-label">纳税人识别号:</text>
<text class="info-value">{{ taxPayerInfo.taxId }}</text>
</view>
<view class="info-row">
<text class="info-label">登记注册类型:</text>
<text class="info-value">{{ taxPayerInfo.registerType }}</text>
</view>
<view class="info-row">
<text class="info-label">行业类型:</text>
<text class="info-value">{{ taxPayerInfo.industry }}</text>
</view>
<view class="info-row">
<text class="info-label">主管税务机关:</text>
<text class="info-value">{{ taxPayerInfo.taxAuthority }}</text>
</view>
</view>
<view class="info-group">
<view class="group-title">人员信息</view>
<view class="info-row">
<text class="info-label">法定代表人:</text>
<text class="info-value">{{ taxPayerInfo.legalPerson }}</text>
</view>
<view class="info-row">
<text class="info-label">财务负责人:</text>
<text class="info-value">{{ taxPayerInfo.financialManager }}</text>
</view>
<view class="info-row">
<text class="info-label">办税人员:</text>
<text class="info-value">{{ taxPayerInfo.taxAgent }}</text>
</view>
<view class="info-row">
<text class="info-label">联系电话:</text>
<text class="info-value">{{ taxPayerInfo.contactPhone }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 申报缴税信息 -->
<view v-if="declarationRecords.length > 0" class="declaration-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">申报缴税信息</text>
<view class="section-actions">
<!-- <tn-button size="sm" type="primary" plain @click="exportDeclarationData">
<uni-icons type="download" size="16" color="#1890ff"></uni-icons>
导出数据
</tn-button> -->
</view>
</view>
<view class="time-filter">
<tn-button v-for="period in timePeriods" :key="period.value" size="sm"
:type="currentPeriod === period.value ? 'primary' : 'default'"
@click="changeTimePeriod(period.value)">
{{ period.label }}
</tn-button>
</view>
<uni-table border stripe emptyText="暂无申报数据">
<uni-tr>
<uni-th width="120" align="center">税款所属期</uni-th>
<uni-th width="100" align="center">税种</uni-th>
<uni-th width="100" align="center">申报期限</uni-th>
<uni-th width="100" align="center">申报状态</uni-th>
<uni-th width="120" align="center">应纳税额</uni-th>
<uni-th width="120" align="center">已缴税额</uni-th>
<uni-th width="100" align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(record, index) in filteredDeclarationRecords" :key="index">
<uni-td align="center">{{ record.taxPeriod }}</uni-td>
<uni-td align="center">{{ record.taxType }}</uni-td>
<uni-td align="center">{{ record.deadline }}</uni-td>
<uni-td align="center">
<view class="status-badge" :class="getDeclarationStatusClass(record.status)">
{{ record.status }}
</view>
</uni-td>
<uni-td align="center">¥{{ record.taxPayable }}</uni-td>
<uni-td align="center">¥{{ record.taxPaid }}</uni-td>
<uni-td align="center">
<tn-button size="sm" type="primary" plain @click="viewDeclarationDetail(record)">
查看
</tn-button>
</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
<!-- 财务报表数据 -->
<view v-if="financialReports.length > 0" class="financial-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">财务报表数据</text>
<text class="report-period">报表期间: {{ currentReportPeriod }}</text>
</view>
<view class="reports-tabs">
<tn-tabs v-model="currentReportType" :list="reportTypes" @change="onReportTypeChange"></tn-tabs>
</view>
<view class="financial-data">
<view class="balance-sheet" v-if="currentReportType === 0">
<view class="table-title">资产负债表</view>
<uni-table border size="small">
<uni-tr>
<uni-th width="200" align="left">资产项目</uni-th>
<uni-th width="150" align="right">期末余额</uni-th>
<uni-th width="200" align="left">负债和权益项目</uni-th>
<uni-th width="150" align="right">期末余额</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in balanceSheet" :key="index">
<uni-td align="left">{{ item.assetItem }}</uni-td>
<uni-td align="right">{{ item.assetAmount }}</uni-td>
<uni-td align="left">{{ item.liabilityItem }}</uni-td>
<uni-td align="right">{{ item.liabilityAmount }}</uni-td>
</uni-tr>
</uni-table>
</view>
<view class="profit-table" v-if="currentReportType === 1">
<view class="table-title">利润表</view>
<uni-table border size="small">
<uni-tr>
<uni-th width="250" align="left">项目</uni-th>
<uni-th width="150" align="right">本期金额</uni-th>
<uni-th width="150" align="right">上期金额</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in profitStatement" :key="index">
<uni-td align="left">{{ item.item }}</uni-td>
<uni-td align="right">{{ item.currentAmount }}</uni-td>
<uni-td align="right">{{ item.previousAmount }}</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
</view>
</view>
<!-- 发票使用信息 -->
<view v-if="invoiceStats" class="invoice-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">发票使用信息</text>
<view class="invoice-stats">
<text class="stat-item">本年开票: {{ invoiceStats.yearIssued }}张</text>
<text class="stat-item">本年收票: {{ invoiceStats.yearReceived }}张</text>
</view>
</view>
<view class="invoice-overview">
<view class="overview-item">
<text class="overview-value">{{ invoiceStats.totalIssued }}</text>
<text class="overview-label">累计开具</text>
</view>
<view class="overview-item">
<text class="overview-value">{{ invoiceStats.totalReceived }}</text>
<text class="overview-label">累计取得</text>
</view>
<view class="overview-item">
<text class="overview-value">{{ invoiceStats.creditAmount }}万</text>
<text class="overview-label">进项税额</text>
</view>
<view class="overview-item">
<text class="overview-value">{{ invoiceStats.taxAmount }}万</text>
<text class="overview-label">销项税额</text>
</view>
</view>
<view class="invoice-actions">
<tn-button size="sm" type="primary" plain @click="viewInvoiceList('issued')">
查看开票记录
</tn-button>
<tn-button size="sm" type="primary" plain @click="viewInvoiceList('received')">
查看收票记录
</tn-button>
<tn-button size="sm" type="primary" plain @click="invoiceVerification">
发票查验
</tn-button>
</view>
</view>
</view>
<!-- 纳税评估信息 -->
<view v-if="taxAssessment" class="assessment-section">
<view class="section-card">
<view class="section-header">
<text class="section-title">纳税评估信息</text>
<view class="risk-level" :class="getRiskLevelClass(taxAssessment.riskLevel)">
风险等级: {{ taxAssessment.riskLevel }}
</view>
</view>
<view class="assessment-content">
<view class="risk-indicators">
<view class="indicator-item" v-for="indicator in taxAssessment.riskIndicators"
:key="indicator.name">
<text class="indicator-name">{{ indicator.name }}</text>
<view class="indicator-bar">
<view class="indicator-progress" :class="'level-' + indicator.level"
:style="{ width: indicator.value + '%' }"></view>
</view>
<text class="indicator-value">{{ indicator.value }}%</text>
</view>
</view>
<view class="assessment-notes" v-if="taxAssessment.notes">
<view class="notes-title">评估说明</view>
<text class="notes-content">{{ taxAssessment.notes }}</text>
</view>
<view class="suggestions" v-if="taxAssessment.suggestions">
<view class="suggestions-title">处理建议</view>
<text class="suggestions-content">{{ taxAssessment.suggestions }}</text>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="searched && !taxPayerInfo" class="empty-section">
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
<text class="empty-text">未找到对应的纳税人信息</text>
<text class="empty-tips">请检查查询条件是否正确</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
//
const searchType = ref(0) // 0:, 1:
const searchValue = ref('')
const loading = ref(false)
const searched = ref(false)
const tabList = [
{ name: '' },
{ name: '' }
]
const placeholderText = computed(() => {
return searchType.value === 0 ? '请输入纳税人票号' : '请输入手机号码'
})
// 纳税人信息
const taxPayerInfo = ref<any>(null)
// 申报缴税信息
const declarationRecords = ref<any[]>([])
const currentPeriod = ref('currentYear')
const timePeriods = [
{ label: '本年度', value: 'currentYear' },
{ label: '上年度', value: 'lastYear' },
{ label: '本季度', value: 'currentQuarter' },
{ label: '自定义', value: 'custom' }
]
const filteredDeclarationRecords = computed(() => {
// 根据选择的时间周期过滤数据
return declarationRecords.value.filter(record => {
// 这里根据实际业务逻辑过滤
return true
})
})
// 财务报表
const financialReports = ref<any[]>([])
const currentReportType = ref(0)
const currentReportPeriod = ref('2024年第三季度')
const reportTypes = [
{ name: '资产负债表' },
{ name: '利润表' },
{ name: '现金流量表' }
]
// 发票信息
const invoiceStats = ref<any>(null)
// 纳税评估
const taxAssessment = ref<any>(null)
// 切换查询类型
const onTabChange = (index : number) => {
searchType.value = index
searchValue.value = ''
resetData()
}
// 查询纳税人信息
const handleSearch = async () => {
if (!searchValue.value.trim()) {
uni.showToast({
title: `请输入${searchType.value === 0 ? '票号' : '手机号'}`,
icon: 'none'
})
return
}
loading.value = true
searched.value = true
try {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 1500))
// 模拟返回数据
taxPayerInfo.value = {
name: '某某科技有限公司',
taxId: '91440101MA5XXXXXX',
registerType: '有限责任公司',
industry: '软件和信息技术服务业',
taxAuthority: '某某市税务局第一分局',
taxStatus: '正常',
creditLevel: 'A',
legalPerson: '张三',
financialManager: '李四',
taxAgent: '王五',
contactPhone: '13800138000'
}
// 初始化其他模块数据
initDeclarationData()
initFinancialData()
initInvoiceData()
initAssessmentData()
uni.showToast({
title: '查询成功',
icon: 'success'
})
} catch (error) {
console.error('查询失败:', error)
uni.showToast({
title: '查询失败,请重试',
icon: 'none'
})
} finally {
loading.value = false
}
}
// 重置数据
const resetData = () => {
taxPayerInfo.value = null
declarationRecords.value = []
financialReports.value = []
invoiceStats.value = null
taxAssessment.value = null
searched.value = false
}
// 初始化申报数据
const initDeclarationData = () => {
declarationRecords.value = [
{
taxPeriod: '2024-09',
taxType: '增值税',
deadline: '2024-10-25',
status: '已申报',
taxPayable: '125,680.50',
taxPaid: '125,680.50'
},
{
taxPeriod: '2024-09',
taxType: '企业所得税',
deadline: '2024-10-31',
status: '已申报',
taxPayable: '89,450.00',
taxPaid: '89,450.00'
},
{
taxPeriod: '2024-08',
taxType: '增值税',
deadline: '2024-09-25',
status: '已申报',
taxPayable: '118,920.30',
taxPaid: '118,920.30'
}
]
}
// 初始化财务数据
const initFinancialData = () => {
// 这里初始化财务报表数据
financialReports.value = [
// 财务报表数据
]
}
// 初始化发票数据
const initInvoiceData = () => {
invoiceStats.value = {
totalIssued: '1,245',
totalReceived: '892',
yearIssued: '356',
yearReceived: '278',
creditAmount: '45.8',
taxAmount: '67.2'
}
}
// 初始化评估数据
const initAssessmentData = () => {
taxAssessment.value = {
riskLevel: '中风险',
riskIndicators: [
{ name: '申报及时性', value: 85, level: 1 },
{ name: '税款缴纳', value: 92, level: 1 },
{ name: '发票合规', value: 78, level: 2 },
{ name: '财务规范', value: 65, level: 3 }
],
notes: '该纳税人发票使用存在一定风险,建议加强发票管理。',
suggestions: '1. 加强发票真伪查验2. 规范财务核算3. 定期进行税务自查。'
}
}
// 状态样式处理
const getTaxStatusClass = (status : string) => {
const classMap : any = {
'正常': 'status-normal',
'非正常': 'status-abnormal',
'注销': 'status-cancelled'
}
return classMap[status] || 'status-normal'
}
const getCreditLevelClass = (level : string) => {
const classMap : any = {
'A': 'credit-a',
'B': 'credit-b',
'C': 'credit-c',
'D': 'credit-d'
}
return classMap[level] || 'credit-a'
}
const getDeclarationStatusClass = (status : string) => {
const classMap : any = {
'已申报': 'status-completed',
'未申报': 'status-pending',
'逾期': 'status-overdue'
}
return classMap[status] || 'status-pending'
}
const getRiskLevelClass = (level : string) => {
const classMap : any = {
'低风险': 'risk-low',
'中风险': 'risk-medium',
'高风险': 'risk-high'
}
return classMap[level] || 'risk-low'
}
// 时间周期切换
const changeTimePeriod = (period : string) => {
currentPeriod.value = period
// 这里根据选择的时间周期重新加载数据
}
// 报表类型切换
const onReportTypeChange = (index : number) => {
currentReportType.value = index
}
// 资产负债表数据
const balanceSheet = ref([
{ assetItem: '货币资金', assetAmount: '1,250,000', liabilityItem: '短期借款', liabilityAmount: '500,000' },
{ assetItem: '应收账款', assetAmount: '890,000', liabilityItem: '应付账款', liabilityAmount: '320,000' },
{ assetItem: '存货', assetAmount: '650,000', liabilityItem: '应交税费', liabilityAmount: '125,680' },
{ assetItem: '固定资产', assetAmount: '2,100,000', liabilityItem: '实收资本', liabilityAmount: '3,000,000' },
{ assetItem: '资产总计', assetAmount: '4,890,000', liabilityItem: '负债和权益总计', liabilityAmount: '4,890,000' }
])
// 利润表数据
const profitStatement = ref([
{ item: '营业收入', currentAmount: '2,580,000', previousAmount: '2,350,000' },
{ item: '营业成本', currentAmount: '1,850,000', previousAmount: '1,680,000' },
{ item: '营业利润', currentAmount: '456,000', previousAmount: '412,000' },
{ item: '利润总额', currentAmount: '445,000', previousAmount: '405,000' },
{ item: '净利润', currentAmount: '356,000', previousAmount: '324,000' }
])
// 操作方法
const exportDeclarationData = () => {
uni.showToast({
title: '数据导出中...',
icon: 'success'
})
}
const viewDeclarationDetail = (record : any) => {
uni.navigateTo({
url: `/pages/declaration/detail?id=${record.taxPeriod}-${record.taxType}`
})
}
const viewInvoiceList = (type : string) => {
uni.navigateTo({
url: `/pages/invoice/list?type=${type}&taxId=${taxPayerInfo.value.taxId}`
})
}
const invoiceVerification = () => {
uni.navigateTo({
url: '/pages/invoice/verification'
})
}
const backToIndex = () => {
uni.navigateTo({
url: '/pages/index/index'
})
}
onLoad((options) => {
// 支持从外部传入查询参数
if (options.ticketNo) {
searchType.value = 0
searchValue.value = options.ticketNo
handleSearch()
} else if (options.phone) {
searchType.value = 1
searchValue.value = options.phone
handleSearch()
}
})
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background-color: #f5f7fa;
}
.content {
padding: 6vh 20px 0 20px;
}
// 搜索区域
.search-section {
margin-bottom: 30rpx;
.search-card {
background: #fff;
border: 1px solid #ddd;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
.input-row {
display: flex;
gap: 20rpx;
align-items: center;
margin-top: 20rpx;
.search-input {
flex: 1;
}
.search-btn {
width: 200rpx;
height: 32px;
}
}
}
}
// 通用卡片样式
.section-card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
}
// 纳税人基础信息
.info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40rpx;
.info-group {
.group-title {
font-size: 28rpx;
font-weight: bold;
color: #1890ff;
margin-bottom: 20rpx;
padding-bottom: 10rpx;
border-bottom: 2rpx solid #1890ff;
}
.info-row {
display: flex;
margin-bottom: 20rpx;
.info-label {
width: 160rpx;
font-size: 26rpx;
color: #666;
flex-shrink: 0;
}
.info-value {
flex: 1;
font-size: 26rpx;
color: #333;
font-weight: 500;
}
}
}
}
// 状态标签
.status-badges {
display: flex;
gap: 15rpx;
}
.status-badge {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
font-weight: 500;
&.status-normal {
background: #f6ffed;
color: #52c41a;
border: 1rpx solid #b7eb8f;
}
&.credit-a {
background: #f6ffed;
color: #52c41a;
border: 1rpx solid #b7eb8f;
}
&.credit-b {
background: #e6f7ff;
color: #1890ff;
border: 1rpx solid #91d5ff;
}
&.status-completed {
background: #f6ffed;
color: #52c41a;
}
&.status-pending {
background: #fffbe6;
color: #faad14;
}
}
// 申报信息
.time-filter {
display: flex;
gap: 15rpx;
margin-bottom: 20rpx;
flex-wrap: wrap;
}
.section-actions {
display: flex;
gap: 15rpx;
}
// 财务报表
.reports-tabs {
margin-bottom: 20rpx;
}
.table-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 15rpx;
text-align: center;
}
// 发票信息
.invoice-stats {
display: flex;
gap: 20rpx;
.stat-item {
font-size: 24rpx;
color: #666;
}
}
.invoice-overview {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
margin-bottom: 30rpx;
text-align: center;
.overview-item {
.overview-value {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #1890ff;
margin-bottom: 8rpx;
}
.overview-label {
font-size: 22rpx;
color: #999;
}
}
}
.invoice-actions {
display: flex;
gap: 15rpx;
justify-content: center;
}
// 纳税评估
.risk-level {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
font-weight: 500;
&.risk-low {
background: #f6ffed;
color: #52c41a;
border: 1rpx solid #b7eb8f;
}
&.risk-medium {
background: #fffbe6;
color: #faad14;
border: 1rpx solid #ffe58f;
}
&.risk-high {
background: #fff2f0;
color: #ff4d4f;
border: 1rpx solid #ffccc7;
}
}
.risk-indicators {
margin-bottom: 30rpx;
.indicator-item {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.indicator-name {
width: 200rpx;
font-size: 26rpx;
color: #333;
}
.indicator-bar {
flex: 1;
height: 20rpx;
background: #f0f0f0;
border-radius: 10rpx;
margin: 0 15rpx;
overflow: hidden;
.indicator-progress {
height: 100%;
border-radius: 10rpx;
transition: width 0.3s;
&.level-1 {
background: #52c41a;
}
&.level-2 {
background: #faad14;
}
&.level-3 {
background: #ff4d4f;
}
}
}
.indicator-value {
width: 80rpx;
font-size: 24rpx;
color: #666;
text-align: right;
}
}
}
.assessment-notes,
.suggestions {
margin-bottom: 20rpx;
.notes-title,
.suggestions-title {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.notes-content,
.suggestions-content {
font-size: 24rpx;
color: #666;
line-height: 1.6;
}
}
// 空状态
.empty-section {
text-align: center;
padding: 100rpx 0;
.empty-text {
display: block;
margin-top: 20rpx;
font-size: 28rpx;
color: #666;
}
.empty-tips {
display: block;
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
}
}
// 响应式设计
@media (max-width: 768px) {
.info-grid {
grid-template-columns: 1fr;
gap: 30rpx;
}
.invoice-overview {
grid-template-columns: repeat(2, 1fr);
}
}
</style>