refactor(webapp): 重构发票验证功能
- 修改基础 URL为本地地址 - 优化发票验证和列表查询逻辑 - 更新数据库结构和查询语句 - 改进前端发票管理页面,增加验证结果展示 - 修复后端发票列表接口,支持 JSON 请求
This commit is contained in:
parent
c22a509633
commit
1e24287327
@ -38,7 +38,7 @@ class DataService:
|
|||||||
purchaserBankAccountInfo, purchaserContactInfo, purchaserName,
|
purchaserBankAccountInfo, purchaserContactInfo, purchaserName,
|
||||||
purchaserTaxNumber, recipient, remarks, reviewer,
|
purchaserTaxNumber, recipient, remarks, reviewer,
|
||||||
sellerBankAccountInfo, sellerContactInfo, sellerName, sellerTaxNumber,
|
sellerBankAccountInfo, sellerContactInfo, sellerName, sellerTaxNumber,
|
||||||
specialTag, title, totalAmount, totalAmountInWords,file_path,verify_time,cyjgxx,
|
specialTag, title, totalAmount, totalAmountInWords,file_path,verify_time,
|
||||||
verify_time,verify_status,desc,desc_files,status
|
verify_time,verify_status,desc,desc_files,status
|
||||||
from invoice
|
from invoice
|
||||||
"""
|
"""
|
||||||
@ -124,14 +124,15 @@ class DataService:
|
|||||||
invoice_id = cursor.lastrowid
|
invoice_id = cursor.lastrowid
|
||||||
return invoice_id
|
return invoice_id
|
||||||
# 更新发票状态
|
# 更新发票状态
|
||||||
def update_invoice_status(self, invoice_id: int, verify_status: str):
|
def update_invoice_status(self, invoice_id: int, verify_status: str,inspectionAmount :str ):
|
||||||
conn = DBService().get_conn()
|
conn = DBService().get_conn()
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"UPDATE invoice SET verify_time = ?,"
|
"UPDATE invoice SET verify_time = ?,"
|
||||||
"verify_status = ?"
|
"verify_status = ?"
|
||||||
|
"inspectionAmount = ?"
|
||||||
"WHERE id = ?",
|
"WHERE id = ?",
|
||||||
(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), verify_status, invoice_id))
|
(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), verify_status,inspectionAmount, invoice_id))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
def update_invoice_desc(self, invoice_id: int|str, desc: str, desc_file: str,status: str):
|
def update_invoice_desc(self, invoice_id: int|str, desc: str, desc_file: str,status: str):
|
||||||
conn = DBService().get_conn()
|
conn = DBService().get_conn()
|
||||||
@ -145,20 +146,20 @@ class DataService:
|
|||||||
(desc, desc_file,status, invoice_id))
|
(desc, desc_file,status, invoice_id))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
# 查询验证记录
|
# 查询验证记录
|
||||||
def get_verify_log(self, file_path: str) -> dict[Any, Any]:
|
def get_verify_log(self, file_path: str) -> dict[Any, Any]|None:
|
||||||
conn = DBService().get_conn()
|
conn = DBService().get_conn()
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
select inspectionAmount,cyjgxx,verify_time,file_path from verify_log where file_path = ? order verify_time desc limit 1
|
select inspectionAmount,cyjgxx,verify_time,file_path from verify_log where file_path = ? order by verify_time desc limit 1
|
||||||
"""
|
"""
|
||||||
, (file_path,))
|
, (file_path,))
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
data = {}
|
|
||||||
if len(rows) > 0:
|
if len(rows) > 0:
|
||||||
|
data = {}
|
||||||
for i in range(len(rows[0])):
|
for i in range(len(rows[0])):
|
||||||
data[cursor.description[i][0]] = rows[0][i]
|
data[cursor.description[i][0]] = rows[0][i]
|
||||||
return data
|
return data
|
||||||
|
return None
|
||||||
# 插入验证记录
|
# 插入验证记录
|
||||||
def insert_verify_log(self, inspection_amount: str, cyjgxx: str, file_path: str):
|
def insert_verify_log(self, inspection_amount: str, cyjgxx: str, file_path: str):
|
||||||
conn = DBService().get_conn()
|
conn = DBService().get_conn()
|
||||||
@ -196,18 +197,18 @@ class DataService:
|
|||||||
purchaserBankAccountInfo, purchaserContactInfo, purchaserName,
|
purchaserBankAccountInfo, purchaserContactInfo, purchaserName,
|
||||||
purchaserTaxNumber, recipient, remarks, reviewer,
|
purchaserTaxNumber, recipient, remarks, reviewer,
|
||||||
sellerBankAccountInfo, sellerContactInfo, sellerName, sellerTaxNumber,
|
sellerBankAccountInfo, sellerContactInfo, sellerName, sellerTaxNumber,
|
||||||
specialTag, title, totalAmount, totalAmountInWords,file_path,verify_time,verify_status,desc,desc_files,status
|
specialTag, title, totalAmount, totalAmountInWords,file_path,verify_time,verify_status,inspectionAmount,desc,desc_files,status
|
||||||
from invoice where
|
from invoice where
|
||||||
"""
|
"""
|
||||||
if time_out != 'all':
|
if time_out != 'all':
|
||||||
sql += " date('now', '-"+time_out+" day') >= date(verify_time) and verify_status == 'success' "
|
sql += " date('now', '-"+time_out+" day') >= date(verify_time) and verify_status == 'success' "
|
||||||
else:
|
else:
|
||||||
sql += " verify_status = " + verify_status
|
sql += " verify_status = '" + verify_status+"'"
|
||||||
if start_date is not None:
|
if start_date is not None:
|
||||||
sql += " and verify_time >= '" + start_date.strftime("%Y-%m-%d") + "'"
|
sql += " and verify_time >= '" + start_date.strftime("%Y-%m-%d") + "'"
|
||||||
if end_date is not None:
|
if end_date is not None:
|
||||||
sql += " and verify_time <= '" + end_date.strftime("%Y-%m-%d") + "'"
|
sql += " and verify_time <= '" + end_date.strftime("%Y-%m-%d") + "'"
|
||||||
if value != '':
|
if value is not None and value != '':
|
||||||
sql += " and ( "
|
sql += " and ( "
|
||||||
sql += "file_path like '%" + value + "%' or "
|
sql += "file_path like '%" + value + "%' or "
|
||||||
sql += "checkCode like '%" + value + "%' or "
|
sql += "checkCode like '%" + value + "%' or "
|
||||||
@ -242,43 +243,13 @@ class DataService:
|
|||||||
sql += "desc_files like '%" + value + "%' "
|
sql += "desc_files like '%" + value + "%' "
|
||||||
sql += ")"
|
sql += ")"
|
||||||
sql += " order by verify_time desc"
|
sql += " order by verify_time desc"
|
||||||
|
print(sql)
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
data = []
|
datas = []
|
||||||
for row in rows:
|
for row in rows:
|
||||||
data.append({
|
data = {}
|
||||||
'checkCode': row[0],
|
for i in range(len(row)):
|
||||||
'drawer': row[1],
|
data[cursor.description[i][0]] = row[i]
|
||||||
'formType': row[2],
|
datas.append(data)
|
||||||
'invoiceAmountPreTax': row[3],
|
return datas
|
||||||
'invoiceCode': row[4],
|
|
||||||
'invoiceDate': row[5],
|
|
||||||
'invoiceNumber': row[6],
|
|
||||||
'invoiceTax': row[7],
|
|
||||||
'invoiceType': row[8],
|
|
||||||
'machineCode': row[9],
|
|
||||||
'passwordArea': row[10],
|
|
||||||
'printedInvoiceCode': row[11],
|
|
||||||
'printedInvoiceNumber': row[12],
|
|
||||||
'purchaserBankAccountInfo': row[13],
|
|
||||||
'purchaserContactInfo': row[14],
|
|
||||||
'purchaserName': row[15],
|
|
||||||
'purchaserTaxNumber': row[16],
|
|
||||||
'recipient': row[17],
|
|
||||||
'remarks': row[18],
|
|
||||||
'reviewer': row[19],
|
|
||||||
'sellerBankAccountInfo': row[20],
|
|
||||||
'sellerContactInfo': row[21],
|
|
||||||
'sellerName': row[22],
|
|
||||||
'sellerTaxNumber': row[23],
|
|
||||||
'specialTag': row[24],
|
|
||||||
'title': row[25],
|
|
||||||
'totalAmount': row[26],
|
|
||||||
'totalAmountInWords': row[27],
|
|
||||||
'file_path': row[28],
|
|
||||||
'verify_time': row[29],
|
|
||||||
'verify_status': row[30],
|
|
||||||
'desc': row[31],
|
|
||||||
'desc_files': row[32]
|
|
||||||
})
|
|
||||||
return data
|
|
||||||
@ -117,6 +117,7 @@ class DBService:
|
|||||||
file_path TEXT, -- 文件哈希
|
file_path TEXT, -- 文件哈希
|
||||||
verify_time TEXT, -- 验证时间
|
verify_time TEXT, -- 验证时间
|
||||||
verify_status TEXT, -- 验证结果
|
verify_status TEXT, -- 验证结果
|
||||||
|
inspectionAmount TEXT, -- 验证次数
|
||||||
desc TEXT, -- 备注
|
desc TEXT, -- 备注
|
||||||
desc_files TEXT, -- 备注附件
|
desc_files TEXT, -- 备注附件
|
||||||
status TEXT, -- 是否报销(yes,no)
|
status TEXT, -- 是否报销(yes,no)
|
||||||
|
|||||||
@ -65,8 +65,8 @@ def reverify():
|
|||||||
# 发票列表
|
# 发票列表
|
||||||
@app.route('/listInvoice',methods=['POST'])
|
@app.route('/listInvoice',methods=['POST'])
|
||||||
def list_invoice():
|
def list_invoice():
|
||||||
value = request.form.get('value')
|
value = request.json.get('value')
|
||||||
verify_status = request.form.get('verifyStatus')
|
verify_status = request.json.get('verify_status')
|
||||||
return dataservice.get_invoice_list(value=value,verify_status=verify_status)
|
return dataservice.get_invoice_list(value=value,verify_status=verify_status)
|
||||||
@app.route('/listInvoiceTimeOut',methods=['POST'])
|
@app.route('/listInvoiceTimeOut',methods=['POST'])
|
||||||
def list_invoice_time_out():
|
def list_invoice_time_out():
|
||||||
|
|||||||
@ -71,8 +71,8 @@ class Service:
|
|||||||
# 复验
|
# 复验
|
||||||
if not reverify:
|
if not reverify:
|
||||||
data1 = dataservice.get_verify_log(file_path=file_path)
|
data1 = dataservice.get_verify_log(file_path=file_path)
|
||||||
print(data)
|
print(data1)
|
||||||
if data1 is not None and data1.get('inspectionAmount') > 0:
|
if data1 is not None and int(data1.get('inspectionAmount')) > 0:
|
||||||
return data1
|
return data1
|
||||||
client = Service.create_client()
|
client = Service.create_client()
|
||||||
type = Service.typeDict.get(data.get('invoiceType'))
|
type = Service.typeDict.get(data.get('invoiceType'))
|
||||||
@ -96,13 +96,17 @@ class Service:
|
|||||||
try:
|
try:
|
||||||
resp = client.verify_vatinvoice_with_options(verify_vatinvoice_request, runtime)
|
resp = client.verify_vatinvoice_with_options(verify_vatinvoice_request, runtime)
|
||||||
ConsoleClient.log(UtilClient.to_jsonstring(resp))
|
ConsoleClient.log(UtilClient.to_jsonstring(resp))
|
||||||
resdata = json.loads(UtilClient.to_jsonstring(resp.body.data)).get('data')
|
respjson = json.loads(UtilClient.to_jsonstring(resp.body.data))
|
||||||
|
code = respjson.get('code')
|
||||||
|
if code != '001':
|
||||||
|
return {'cyjgxx': respjson.get('msg'), 'inspectionAmount': -1,'status': 'fail'}
|
||||||
|
resdata = respjson.get('data')
|
||||||
if resdata is None:
|
if resdata is None:
|
||||||
resdata = {'cyjgxx': "未查询到发票信息", 'inspectionAmount': -1,'status': 'fail'}
|
resdata = {'cyjgxx': "未查询到发票信息", 'inspectionAmount': -1,'status': 'fail'}
|
||||||
else:
|
else:
|
||||||
resdata.update({'status': 'success'})
|
resdata.update({'status': 'success'})
|
||||||
dataservice.insert_verify_log(resdata.get('inspectionAmount'), resdata.get('cyjgxx'), file_path)
|
dataservice.insert_verify_log(resdata.get('inspectionAmount'), resdata.get('cyjgxx'), file_path)
|
||||||
dataservice.update_invoice_status(data.get('id'), resdata.get('status'))
|
dataservice.update_invoice_status(data.get('id'), resdata.get('status'), resdata.get('inspectionAmount'))
|
||||||
return resdata
|
return resdata
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
# 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
# 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
|||||||
Binary file not shown.
@ -107,7 +107,7 @@ const emit= defineEmits(['update:formState'])
|
|||||||
|
|
||||||
const fileType = ref<string>('img')
|
const fileType = ref<string>('img')
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
alert(props.filePath)
|
// alert(props.filePath)
|
||||||
if(props.filePath){
|
if(props.filePath){
|
||||||
fileType.value = props.filePath.split('.').pop() ==='pdf'?'pdf':'img'
|
fileType.value = props.filePath.split('.').pop() ==='pdf'?'pdf':'img'
|
||||||
request.get('/recognize?filePath='+encodeURIComponent(props.filePath)).then((res) => {
|
request.get('/recognize?filePath='+encodeURIComponent(props.filePath)).then((res) => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
// SmileOutlined,
|
// SmileOutlined,
|
||||||
} from '@ant-design/icons-vue'
|
} from '@ant-design/icons-vue'
|
||||||
import type {StepProps} from "ant-design-vue"
|
import type {StepProps} from "ant-design-vue"
|
||||||
import Check from './Check.vue'
|
import Check from './Check.vue'
|
||||||
import upload from './upload.vue'
|
import upload from './upload.vue'
|
||||||
import Report from "./report.vue"
|
import Report from "./report.vue"
|
||||||
// 步骤
|
// 步骤
|
||||||
|
|||||||
@ -35,7 +35,8 @@ const handleUpload = (options: any) => {
|
|||||||
if (xhr.status === 200 || xhr.status === 201) {
|
if (xhr.status === 200 || xhr.status === 201) {
|
||||||
console.log(xhr.responseText);
|
console.log(xhr.responseText);
|
||||||
onSuccess(xhr.responseText, file);
|
onSuccess(xhr.responseText, file);
|
||||||
emit('update:filePath', xhr.responseText)
|
let res = JSON.parse(xhr.responseText)
|
||||||
|
emit('update:filePath', res.file_path)
|
||||||
} else {
|
} else {
|
||||||
onError(new Error(`Upload failed with status ${xhr.status}`));
|
onError(new Error(`Upload failed with status ${xhr.status}`));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import {h,ref} from "vue";
|
import {h, onMounted, ref} from "vue";
|
||||||
import {
|
import {
|
||||||
SearchOutlined
|
SearchOutlined
|
||||||
} from '@ant-design/icons-vue'
|
} from '@ant-design/icons-vue'
|
||||||
import request from "#/utils/request.ts";
|
import request from '#/utils/request.ts';
|
||||||
const columns = [
|
const columns = [
|
||||||
// {
|
// {
|
||||||
// title: '发票代码',
|
// title: '发票代码',
|
||||||
@ -49,8 +49,8 @@ const columns = [
|
|||||||
|
|
||||||
{
|
{
|
||||||
title: '查验结果',
|
title: '查验结果',
|
||||||
dataIndex: 'cyjgxx',
|
dataIndex: 'verify_status',
|
||||||
key: 'cyjgxx',
|
key: 'verify_status',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '查验次数',
|
title: '查验次数',
|
||||||
@ -69,20 +69,25 @@ let data = ref( [])
|
|||||||
|
|
||||||
let searchParams = ref({
|
let searchParams = ref({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 100,
|
||||||
data: {
|
current: 1,
|
||||||
status: '1'
|
params: {
|
||||||
|
verify_status: 'success',
|
||||||
|
value: null,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
request.post("/listInvoice", {
|
request.post("/listInvoice", {
|
||||||
verify_status : 'yes'
|
verify_status : 'success'
|
||||||
}).then(( res ) => {
|
}).then(( res ) => {
|
||||||
console.log(res)
|
console.log(res)
|
||||||
|
data.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getList()
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -94,12 +99,12 @@ getList()
|
|||||||
<a-range-picker></a-range-picker>
|
<a-range-picker></a-range-picker>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="销售方">
|
<a-form-item label="销售方">
|
||||||
<a-input></a-input>
|
<a-input v-model="searchParams.params.value"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="验证结果">
|
<a-form-item label="验证结果">
|
||||||
<a-radio-group v-model:value="searchParams.data.status">
|
<a-radio-group v-model:value="searchParams.params.verify_status">
|
||||||
<a-radio-button value="1">正常</a-radio-button>
|
<a-radio-button value="success">正常</a-radio-button>
|
||||||
<a-radio-button value="2">异常</a-radio-button>
|
<a-radio-button value="faild">异常</a-radio-button>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
@ -110,6 +115,12 @@ getList()
|
|||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
<a-table :columns="columns" :data-source="data">
|
<a-table :columns="columns" :data-source="data">
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'verify_status'">
|
||||||
|
<a-tag v-if="record.verify_status === 'success'" color="green">正常</a-tag>
|
||||||
|
<a-tag v-if="record.verify_status === 'fail'" color="red">异常</a-tag>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
export const baseURL = "http://192.168.1.100:5555"
|
export const baseURL = "http://127.0.0.1:5555"
|
||||||
// export const baseURL = "http://101.200.148.149:8555"
|
// export const baseURL = "http://101.200.148.149:8555"
|
||||||
Loading…
Reference in New Issue
Block a user