feat(invoice): 增加发票入账功能

- 新增发票入账相关的前端界面和后端接口
- 实现发票列表的展示、筛选和分页功能
- 添加发票入账状态的切换和备注功能
- 优化发票列表的展示样式,增加扩展行显示备注信息
This commit is contained in:
liuxiaoqing 2025-08-19 17:35:34 +08:00
parent 1e24287327
commit 795620b0f8
4 changed files with 97 additions and 13 deletions

View File

@ -243,7 +243,7 @@ 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) # print(sql)
cursor.execute(sql) cursor.execute(sql)
rows = cursor.fetchall() rows = cursor.fetchall()
datas = [] datas = []

View File

@ -80,10 +80,10 @@ def list_logs():
# 更新发票标注 # 更新发票标注
@app.route('/updateInvoice',methods=['POST']) @app.route('/updateInvoice',methods=['POST'])
def update_invoice(): def update_invoice():
invoice_id = request.form.get('invoiceId') invoice_id = request.json.get('invoiceId')
status = request.form.get('status') status = request.json.get('status')
desc = request.form.get('desc') desc = request.json.get('desc')
desc_files = request.form.get('desc_files') desc_files = request.json.get('desc_files')
return dataservice.update_invoice_desc(invoice_id=invoice_id,desc=desc,desc_file=desc_files,status=status) return dataservice.update_invoice_desc(invoice_id=invoice_id,desc=desc,desc_file=desc_files,status=status)
if __name__ == '__main__': if __name__ == '__main__':
# Service.verify(sys.argv[1:]) # Service.verify(sys.argv[1:])

View File

@ -2,19 +2,30 @@
import {h, onMounted, ref} from "vue"; import {h, onMounted, ref} from "vue";
import { import {
SearchOutlined SearchOutlined,
FileSearchOutlined
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import request from '#/utils/request.ts'; import request from '#/utils/request.ts';
import {baseURL} from "../utils/baseurl.ts";
import type {TableProps} from "ant-design-vue";
interface DataType {
id: string;
status: string;
desc: string;
desc_list: string;
}
const columns = [ const columns = [
// { // {
// title: '', // title: '',
// dataIndex: 'invoiceCode', // dataIndex: 'status',
// key: 'invoiceCode', // key: 'status',
// showSelection: true,
// }, // },
{ {
title: '发票号码', title: '发票号码',
dataIndex: 'invoiceNumber', dataIndex: 'invoiceNumber',
key: 'invoiceNumber', key: 'invoiceNumber',
// showSelection: true,
}, },
{ {
title: '销方名称', title: '销方名称',
@ -61,6 +72,11 @@ const columns = [
title: '查验时间', title: '查验时间',
dataIndex: 'verify_time', dataIndex: 'verify_time',
key: 'verify_time', key: 'verify_time',
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
} }
] ]
@ -70,13 +86,53 @@ let data = ref( [])
let searchParams = ref({ let searchParams = ref({
page: 1, page: 1,
pageSize: 100, pageSize: 100,
current: 1, total: 0,
params: { params: {
verify_status: 'success', verify_status: 'success',
value: null, value: null,
} }
}); });
//
const rowSelection: TableProps['rowSelection'] = {
onChange: (selectedRowKeys: string[], selectedRows: DataType[]) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
getCheckboxProps: (record: DataType) => ({
disabled: record.status === 'yes', // Column configuration not to be checked
name: record.status,
}),
};
//
const openModal = ref(false);
const modalTitle = ref('')
const confirmLoading = ref(false);
const formData = ref({
id: '',
status: false,
desc: '',
desc_files: '',
});
const handleOk = () => {
confirmLoading.value = true;
request.post("/updateInvoice", {
invoiceId: formData.value.id,
status: formData.value.status?'yes':'no',
desc: formData.value.desc,
desc_files: formData.value.desc_files,
}).then(( res ) => {
console.log(res)
if (res.code === 200) {
openModal.value = false;
confirmLoading.value = false;
}
})
};
const handleOpen = (record) => {
formData.value = record
openModal.value = true;
};
//
const getList = () => { const getList = () => {
request.post("/listInvoice", { request.post("/listInvoice", {
verify_status : 'success' verify_status : 'success'
@ -114,16 +170,44 @@ onMounted(() => {
</a-col> </a-col>
</a-row> </a-row>
</div> </div>
<a-table :columns="columns" :data-source="data"> <a-table :columns="columns" :data-source="data" :row-selection="rowSelection" >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'verify_status'"> <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 === 'success'" color="green">正常</a-tag>
<a-tag v-if="record.verify_status === 'fail'" color="red">异常</a-tag> <a-tag v-if="record.verify_status === 'fail'" color="red">异常</a-tag>
</template> </template>
<template v-if="column.key === 'action'" >
<a-button type="primary" v-if="record.status ==='yes'">备注</a-button>
<a-button type="primary" v-if="!record.status" @click="handleOpen(record)">入账</a-button>
</template>
</template>
<template #expandedRowRender="{ record }">
<a-row >
<a-col :span="16">
<a-typography-title :level="4" >备注</a-typography-title>
<a-typography-paragraph>
<blockquote>{{ record.desc }}asdsad</blockquote>
</a-typography-paragraph>
</a-col>
<a-col :span="8">
<a-image-preview-group>
<a-image :width="200" v-for="file in record.desc_list.split(',')" :src="baseURL+file"/>
</a-image-preview-group>
</a-col>
</a-row>
</template>
<template #expandColumnTitle>
<FileSearchOutlined />
</template> </template>
</a-table> </a-table>
<a-modal v-model:open="openModal" title="Title" :confirm-loading="confirmLoading" @ok="handleOk">
<a-form v-model:value="formData" layout="vertical">
<a-form-item label="是否入账">
<a-switch v-model:value="formData.status"></a-switch>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
<style scoped> <style scoped>
.table-operations { .table-operations {
margin-bottom: 16px; margin-bottom: 16px;

View File

@ -59,7 +59,7 @@ button:focus-visible {
} }
#app { #app {
max-width: 1280px; /*max-width: 1280px;*/
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0 auto; margin: 0 auto;