123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- <script setup lang="ts">
- import AForm from '@/components/AForm/index.vue'
- import { FormConfigType } from '@/components/AForm/type'
- import { ToolbarConfigType } from '@/components/AToolbar/type'
- import { ColumnConfigType } from '@/components/ATable/type'
- import { StrAnyObj, StrAnyObjArr } from '@/typings'
- import { useHandleData } from '@/utils/useHandleData'
- import {
- addApi,
- deleteApi,
- editApi,
- excelExportApi,
- getDetailApi,
- getPageApi,
- retrieveApi
- } from '@/api/business/payment/requests'
- import { getPageApi as getCorporationPageApi } from '@/api/business/corporation/corporation'
- import DeptTreeSelect from '@/views/components/DeptTreeSelect/index.vue'
- import { getPageApi as getCapitalAccountPageApi } from '@/api/business/capital/account'
- import { getDictByCode } from '@/utils/dict'
- import MoneyPDF from '@/components/PDF/moneyPDF.vue'
- import { getPdf } from '@/utils/getPdf.js'
- const queryRef = ref<InstanceType<typeof AForm>>()
- const formRef = ref<InstanceType<typeof AForm>>()
- const showQuery = ref<boolean>(true)
- const selectKeys = ref<string[]>([])
- const pageTotal = ref<number>(0)
- const queryData = ref<StrAnyObj>({ pageNum: 1, pageSize: 10 })
- const tableData = ref<StrAnyObjArr>([])
- const formData = ref<StrAnyObj>({ paymentRequestsDetailList: [{}] })
- const dialogTitle = ref<string>('')
- const dialogVisible = ref<boolean>(false)
- const dialogPrint = ref<boolean>(false)
- const rowData = ref<StrAnyObj>({})
- const deptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()
- const selectDeptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()
- const disabled = ref(false)
- const queryConfig: FormConfigType[] = [
- {
- type: 'select',
- prop: 'corporationId',
- label: '归属公司',
- keyName: 'id',
- labelName: 'name',
- async option() {
- const data = await getCorporationPageApi({ searchAll: true })
- return data.records
- }
- },
- {
- type: 'slot',
- prop: 'deptId',
- label: '归属部门'
- },
- {
- type: 'select',
- prop: 'type',
- label: '请款类型',
- dict: 'payment_requests_type'
- },
- {
- type: 'select',
- prop: 'payType',
- label: '付款方式',
- dict: 'pay_type'
- },
- {
- type: 'select',
- prop: 'approvalStatus',
- label: '审批状态',
- option: [
- {
- key: 0,
- label: '待提交'
- },
- {
- key: 1,
- label: '审批中'
- },
- {
- key: 2,
- label: '审批通过'
- },
- {
- key: 4,
- label: '终止'
- },
- {
- key: 6,
- label: '撤销'
- },
- {
- key: 7,
- label: '取回'
- }
- ]
- },
- {
- type: 'select',
- prop: 'paymentStatus',
- label: '放款状态',
- option: [
- {
- key: 0,
- label: '未打款'
- },
- {
- key: 1,
- label: '部分打款'
- },
- {
- key: 2,
- label: '已打款'
- }
- ]
- }
- ]
- const toolbarConfig: ToolbarConfigType[] = [
- {
- common: 'search',
- click() {
- queryData.value.pageNum = 1
- getPage()
- }
- },
- {
- common: 'reset',
- click() {
- queryRef.value?.resetFields()
- getPage()
- }
- },
- {
- common: 'add',
- click() {
- disabled.value = false
- dialogVisible.value = true
- dialogTitle.value = '新增'
- nextTick(() => deptIdRef.value?.load())
- }
- },
- {
- text: '导出',
- icon: 'Download',
- type: 'primary',
- click() {
- excelExportApi(queryData.value).then(() => {
- ElMessage.success('导出成功')
- })
- }
- }
- ]
- const columnConfig: ColumnConfigType[] = [
- {
- prop: 'corporationName',
- label: '归属公司'
- },
- {
- prop: 'deptName',
- label: '归属部门'
- },
- {
- prop: 'type',
- label: '请款类型',
- dict: 'payment_requests_type'
- },
- {
- prop: 'userName',
- label: '请款人'
- },
- {
- prop: 'createTime',
- label: '请款时间'
- },
- {
- prop: 'useTime',
- label: '用款时间'
- },
- {
- prop: 'useRemark',
- label: '用款说明',
- showOverflowTooltip: true
- },
- {
- prop: 'totalAmount',
- label: '请款金额'
- },
- {
- prop: 'payType',
- label: '付款方式',
- dict: 'pay_type'
- },
- {
- prop: 'capitalAccountName',
- label: '付款账户'
- },
- {
- prop: 'approvalStatus',
- label: '审批状态',
- formatter(row) {
- switch (row.approvalStatus) {
- case 0:
- return '待提交'
- case 1:
- return '审批中'
- case 2:
- return '审批通过'
- case 4:
- return '驳回'
- case 6:
- return '撤销'
- case 7:
- return '取回'
- default:
- return ''
- }
- }
- },
- {
- prop: 'paymentStatus',
- label: '放款状态',
- formatter(row) {
- switch (row.paymentStatus) {
- case 0:
- return '未打款'
- case 1:
- return '部分打款'
- case 2:
- return '已打款'
- default:
- return ''
- }
- }
- },
- {
- width: 250,
- handleConfig: [
- {
- text: '取回',
- if(row){
- return row.approvalStatus == 1
- },
- click(row) {
- retrieveApi({ businessId: row.id }).then(() => {
- ElMessage.success('取回成功')
- getPage()
- })
- }
- },
- {
- text: '重新发起',
- if(row) {
- return row.approvalStatus == 0 || row.approvalStatus == 7
- },
- click(row) {
- dialogVisible.value = true
- dialogTitle.value = '重新发起'
- disabled.value = false
- getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
- formData.value = resp
- })
- nextTick(() => deptIdRef.value?.load())
- }
- },
- {
- common: 'detail',
- click(row) {
- dialogVisible.value = true
- dialogTitle.value = '详情'
- disabled.value = true
- nextTick(() => deptIdRef.value?.load())
- getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
- formData.value = resp
- })
- }
- },
- {
- text: '打印',
- click(row) {
- rowData.value = row
- dialogPrint.value = true
- }
- }
- ]
- }
- ]
- const formConfig: FormConfigType[] = [
- {
- type: 'select',
- prop: 'corporationId',
- label: '归属公司',
- keyName: 'id',
- labelName: 'name',
- async option() {
- const data = await getCorporationPageApi({ searchAll: true })
- return data.records
- },
- rule: [{ required: true, message: '归属公司id不能为空', trigger: 'blur' }]
- },
- {
- type: 'slot',
- prop: 'deptId',
- label: '归属部门',
- rule: [{ required: true, message: '部门id不能为空', trigger: 'blur' }]
- },
- {
- type: 'select',
- prop: 'type',
- label: '请款类型',
- dict: 'payment_requests_type',
- rule: [{ required: true, message: '请款类型不能为空', trigger: 'blur' }]
- },
- {
- type: 'datePicker',
- prop: 'useTime',
- label: '用款时间',
- datePickerType: 'datetime',
- format: 'YYYY-MM-DD HH:mm:ss',
- valueFormat: 'YYYY-MM-DD HH:mm:ss'
- },
- {
- type: 'input',
- itemType: 'textarea',
- prop: 'useRemark',
- label: '用款说明',
- rows: 3,
- span: 24,
- placeholder: '自动拼接请款明细中的款项说明',
- disabled: true
- },
- {
- type: 'upload',
- prop: 'atts',
- label: '上传附件',
- span: 24
- },
- {
- type: 'slot',
- prop: 'detailTable',
- label: '请款明细',
- span: 24
- },
- {
- type: 'input',
- prop: 'totalAmount',
- label: '付款总金额',
- disabled: true,
- placeholder: '自动统计请款明细中的请款金额'
- },
- {
- type: 'inputNumber',
- prop: 'documentQuantity',
- label: '单据数量',
- min: 0,
- precision: 0,
- rule: [{ required: true, message: '单据数量不能为空', trigger: 'blur' }]
- },
- {
- type: 'select',
- prop: 'payType',
- label: '付款方式',
- dict: 'pay_type',
- rule: [{ required: true, message: '付款方式不能为空', trigger: 'blur' }]
- },
- {
- type: 'select',
- prop: 'capitalAccountId',
- label: '付款账户',
- keyName: 'id',
- labelName: 'accountAlias',
- async option() {
- const data = await getCapitalAccountPageApi({ searchAll: true })
- return data.records
- }
- },
- {
- type: 'input',
- prop: 'accountName',
- label: '户名'
- },
- {
- type: 'input',
- prop: 'account',
- label: '银行账号'
- },
- {
- type: 'input',
- prop: 'depositBank',
- label: '开户银行'
- },
- {
- type: 'input',
- prop: 'correspondentNumber',
- label: '联行号/SWIFT Code'
- }
- ]
- const detailTableColumnConfig: ColumnConfigType[] = [
- {
- slot: 'expenseType',
- label: '费用类型',
- width: 250
- },
- {
- slot: 'remark',
- label: '款项说明'
- },
- {
- slot: 'amount',
- label: '请款金额',
- width: 180
- },
- {
- width: 100,
- if: () => !disabled.value,
- handleConfig: [
- {
- common: 'delete',
- click(row, index) {
- formData.value.paymentRequestsDetailList.splice(index, 1)
- updateAmount()
- }
- }
- ]
- }
- ]
- onMounted(() => {
- getPage()
- selectDeptIdRef.value?.load()
- })
- function getPage() {
- getPageApi(queryData.value).then((resp) => {
- tableData.value = resp.records
- pageTotal.value = resp.total
- })
- }
- function tableSelectionChange(item: StrAnyObjArr) {
- selectKeys.value = item.map((item) => item.id)
- }
- function formSubmit() {
- formRef.value?.validate(() => {
- if (formData.value.paymentRequestsDetailList.length === 0) {
- ElMessage.error('请款明细为空,无法提交')
- return
- }
- for (const item of formData.value.paymentRequestsDetailList) {
- if (!item.expenseType) {
- ElMessage.error('请款明细存在费用类型为空,无法提交')
- return
- }
- if (!item.remark) {
- ElMessage.error('请款明细存在款项说明为空,无法提交')
- return
- }
- if (!item.amount) {
- ElMessage.error('请款明细存在请款金额为空,无法提交')
- return
- }
- }
- if (formData.value.id) {
- editApi(formData.value).then(() => {
- dialogVisible.value = false
- ElMessage.success('修改成功')
- getPage()
- })
- } else {
- addApi(formData.value).then(() => {
- dialogVisible.value = false
- ElMessage.success('新增成功')
- getPage()
- })
- }
- })
- }
- function formClosed() {
- formRef.value?.resetFields()
- }
- function handleRemove(idList: string[]) {
- useHandleData('是否确认删除?', () => {
- deleteApi({ idList }).then(() => {
- ElMessage.success('删除成功')
- getPage()
- })
- })
- }
- function addPaymentRequestsDetailList() {
- formData.value.paymentRequestsDetailList.push({})
- }
- async function updateDetailRemark() {
- const expenseTypes = await getDictByCode('expense_type')
- const expenseMap = new Map<number, string>()
- for (const item of expenseTypes) {
- expenseMap.set(item.value, item.label)
- }
- formData.value.useRemark = formData.value.paymentRequestsDetailList
- .map(
- (item) =>
- `【${expenseMap.get(item.expenseType) ?? ''}】 - ${item.remark ?? ''} - ${item.amount ?? ''}`
- )
- .join('\n')
- }
- function updateAmount() {
- formData.value.totalAmount = formData.value.paymentRequestsDetailList
- .map((item) => item.amount)
- .filter((item) => item !== '' && item !== null && item !== undefined)
- .reduce((pre, next) => pre + next, 0)
- updateDetailRemark()
- }
- const printObj = ref({
- id: 'pdfDom',
- popTitle: '',
- extraCss:
- 'https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css',
- extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
- })
- const clickDownload = () => {
- getPdf('请款PDF文件')
- }
- </script>
- <template>
- <div>
- <el-card v-if="showQuery">
- <a-form ref="queryRef" v-model="queryData" :config="queryConfig" :span="6">
- <template #deptId>
- <dept-tree-select ref="selectDeptIdRef" v-model="formData.deptId" />
- </template>
- </a-form>
- </el-card>
- <a-table
- :data="tableData"
- :page-total="pageTotal"
- :toolbar-config="toolbarConfig"
- :column-config="columnConfig"
- v-model:showQuery="showQuery"
- v-model:page-num="queryData.pageNum"
- v-model:page-size="queryData.pageSize"
- @page-num-change="getPage"
- @page-size-change="getPage"
- @selection-change="tableSelectionChange"
- >
- </a-table>
- <a-dialog
- v-if="dialogVisible"
- v-model="dialogVisible"
- :title="dialogTitle"
- :footer="!disabled"
- @submit="formSubmit"
- @closed="formClosed"
- width="1400px"
- height="200px"
- >
- <a-form ref="formRef" v-model="formData" :config="formConfig" :span="12" :disabled="disabled">
- <template #deptId>
- <dept-tree-select ref="deptIdRef" v-model="formData.deptId" :disabled="disabled" />
- </template>
- <template #detailTable>
- <a-table
- :data="formData.paymentRequestsDetailList"
- :columnConfig="detailTableColumnConfig"
- style="width: 100%"
- :card="false"
- >
- <template #expenseType="scope">
- <a-select
- v-model="scope.row.expenseType"
- dict="expense_type"
- :disabled="disabled"
- @change="updateDetailRemark"
- />
- </template>
- <template #remark="scope">
- <a-input
- v-model="scope.row.remark"
- type="textarea"
- :rows="2"
- @change="updateDetailRemark"
- :disabled="disabled"
- />
- </template>
- <template #amount="scope">
- <a-inputNumber
- v-model="scope.row.amount"
- :min="0.01"
- :precision="2"
- @change="updateAmount"
- :disabled="disabled"
- />
- </template>
- </a-table>
- <el-button
- v-if="!disabled"
- style="width: 100%; margin-bottom: 20px"
- type="primary"
- @click="addPaymentRequestsDetailList"
- >
- 添加行
- </el-button>
- </template>
- </a-form>
- </a-dialog>
- <a-dialog :footer="false" v-if="dialogPrint" v-model="dialogPrint" title="打印" width="840px">
- <MoneyPDF :rowData="rowData"></MoneyPDF>
- <template #footer>
- <div>
- <el-button @click="dialogPrint = false" size="large">取消</el-button>
- <el-button type="primary" v-print="printObj" size="large">打印</el-button>
- <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
- </div>
- </template>
- </a-dialog>
- </div>
- </template>
|