权限模板

feature-JimuReport-1106-yjl
sunzehua 1 month ago
parent b9bf639846
commit c787a93052

@ -224,11 +224,11 @@
} }
if (arr[i].bookingSlotSaleInfoList && arr[i].bookingSlotSaleInfoList.length == 1) { if (arr[i].bookingSlotSaleInfoList && arr[i].bookingSlotSaleInfoList.length == 1) {
arr[i].op = arr[i].bookingSlotSaleInfoList[0].op arr[i].op = arr[i].bookingSlotSaleInfoList[0].op
arr[i].customername = arr[i].bookingSlotSaleInfoList[0].customername arr[i].customerName = arr[i].bookingSlotSaleInfoList[0].customerName
arr[i].custservice = arr[i].bookingSlotSaleInfoList[0].custservice arr[i].custService = arr[i].bookingSlotSaleInfoList[0].custService
arr[i].salE_TIME = arr[i].bookingSlotSaleInfoList[0].salE_TIME arr[i].saleTime = arr[i].bookingSlotSaleInfoList[0].saleTime
arr[i].sellingPrice = arr[i].bookingSlotSaleInfoList[0].sellingPrice arr[i].sellingPrice = arr[i].bookingSlotSaleInfoList[0].sellingPrice
arr[i].goodsname = arr[i].bookingSlotSaleInfoList[0].goodsname arr[i].goodsName = arr[i].bookingSlotSaleInfoList[0].goodsName
arr[i].shipper = arr[i].bookingSlotSaleInfoList[0].shipper arr[i].shipper = arr[i].bookingSlotSaleInfoList[0].shipper
arr[i].sale = arr[i].bookingSlotSaleInfoList[0].sale arr[i].sale = arr[i].bookingSlotSaleInfoList[0].sale
arr[i].business = arr[i].bookingSlotSaleInfoList[0].business arr[i].business = arr[i].bookingSlotSaleInfoList[0].business

@ -0,0 +1,35 @@
import { request } from '/@/utils/request'
// 获取列表 (Auth)
export function GetList(parameter) {
return request({
url: '/feeApi/InvoiceApplicationAudit/GetList',
method: 'post',
data: parameter,
})
}
export function InvoiceApplicationGet(parameter) {
return request({
url: '/feeApi/InvoiceApplication/Get',
method: 'get',
params: parameter,
})
}
export function Audit(parameter) {
return request({
url: '/feeApi/InvoiceApplicationAudit/Audit',
method: 'post',
data: parameter,
})
}
export function GetOpFileList(parameter) {
return request({
url: '/mainApi/OpFile/GetOpFileList',
method: 'get',
params:parameter
})
}

@ -0,0 +1,381 @@
import { ref } from 'vue'
import { BasicColumn, FormSchema } from '/@/components/Table'
import { getOptions } from '/@/hooks/dict'
export const billTypeData = [
{ value: '', label: '全部' },
{ value: 1, label: '待审核' },
{ value: 2, label: '已审核' },
]
export const searchFormSchema: FormSchema[] = [
{
field: 'applicationNO',
label: '申请单号',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'applicationNO',
label: '开票金额',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'applyDate',
label: '申请日期',
component: 'RangePicker',
required: false,
dynamicDisabled: false,
colProps: { span: 4 },
componentProps: {
allowClear: true,
},
},
{
field: 'createByName',
label: '申请人',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'status',
label: '审核状态',
component: 'Select',
colProps: { span: 4 },
componentProps: {
options: billTypeData,
},
},
]
//列表
export const columns: BasicColumn[] = [
{
title: '委托单位',
dataIndex: 'applicationNO',
width: 120,
align: 'left',
},
{
title: '主提单号',
dataIndex: 'statusText',
width: 70,
align: 'left',
},
{
title: '提单签发状态',
dataIndex: 'customerName',
width: 100,
align: 'left',
},
{
title: '签单方式',
dataIndex: 'invoiceHeader',
width: 100,
align: 'left',
},
{
title: '最近操作人',
dataIndex: 'currency',
width: 100,
align: 'left',
},
{
title: '操作时间',
dataIndex: 'categoryText',
width: 100,
align: 'left',
},
{
title: '销售',
dataIndex: 'originalAmount',
width: 100,
align: 'left',
},
{
title: '结算方式',
dataIndex: 'createByName',
width: 100,
align: 'left',
},
{
title: '开船日期',
dataIndex: 'applyDate',
width: 100,
align: 'left',
},
{
title: '结算日期',
dataIndex: 'categoryText',
width: 100,
align: 'left',
},
{
title: '特殊放单',
dataIndex: 'createTime',
width: 100,
align: 'left',
},
{
title: '协议天数',
dataIndex: 'taxRate',
width: 100,
align: 'left',
},
{
title: '实际天数',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: 'USD未收',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: 'RMB未收',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '未收合计',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '业务类型',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '起运港',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '卸货港',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '客服',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '船证',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '是否改签',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '特殊放单审批意见',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '经理复核',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '后边是否有货',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '是否超期欠费',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '船证备注',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '签入日期',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '签出日期',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '总应收',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '单证',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
{
title: '签单地点',
dataIndex: 'invoiceNO',
width: 100,
align: 'left',
},
]
//列表
export const detailColumns: BasicColumn[] = [
{
title: '货物或业务应税劳动名称',
dataIndex: 'name',
width: 120,
align: 'left',
},
{
title: '规格型号',
dataIndex: 'specification',
width: 70,
align: 'left',
},
{
title: '单位',
dataIndex: 'unit',
width: 100,
align: 'left',
},
{
title: '数量',
dataIndex: 'quantity',
width: 100,
align: 'left',
},
{
title: '含税单价',
dataIndex: 'taxUnitPrice',
width: 100,
align: 'left',
},
{
title: '单价',
dataIndex: 'unitPrice',
width: 100,
align: 'left',
},
{
title: '金额',
dataIndex: 'amount',
width: 100,
align: 'left',
},
{
title: '税率',
dataIndex: 'taxRate',
width: 100,
align: 'left',
},
{
title: '税额',
dataIndex: 'taxAmount',
width: 100,
align: 'left',
}
]
export const feeColumns: BasicColumn[] = [
{
title: '委托编号',
dataIndex: 'customerNo',
width: 100,
},
{
title: '主提单号',
dataIndex: 'mblno',
width: 100,
},
{
title: '委托单位',
dataIndex: 'customerName',
width: 100,
},
{
title: '开船日期',
dataIndex: 'etd',
width: 150,
},
{
title: '业务来源',
dataIndex: 'sourceName',
width: 80,
},
{
title: '费用名称',
dataIndex: 'feeName',
width: 80,
},
{
title: '收付',
dataIndex: 'feeType',
width: 50,
},
{
title: '申请金额',
dataIndex: 'applyAmount',
width: 80,
},
{
title: '原始币别',
dataIndex: 'originalCurrency',
width: 80,
},
{
title: '原始汇率',
dataIndex: 'originalRate',
width: 80,
},
{
title: '折算汇率',
dataIndex: 'exchangeRate',
width: 80,
},
]
export const feeColumnsSum: BasicColumn[] = [
{
title: '收付',
dataIndex: 'feeType',
width: 100,
},
{
title: '币别',
dataIndex: 'currency',
width: 100,
},
{
title: '金额',
dataIndex: 'amount',
width: 100,
},
]

@ -0,0 +1,527 @@
<template>
<div class="main">
<div class="top">
<BasicTable height="600px" @row-click="handleClick" class="examine-table" @register="registerTable">
<template #tableTitle>
<div class="ds-h-aciton-btns-fee">
<a-tooltip placement="top" :mouseEnterDelay="0.5">
<template #title>
<span>复制</span>
</template>
<span class="ds-action-svg-btn">
<img src="../../../assets/svg/infoclient/fuzhi.svg" class="SvgImg" />
</span>
</a-tooltip>
<a-tooltip placement="top" :mouseEnterDelay="0.5">
<template #title>
<span>删除</span>
</template>
<a-popconfirm title="确定删除当前选中数据?" @confirm="FnDel" ok-text="" cancel-text="">
<span class="ds-action-svg-btn">
<img src="../../../assets/svg/infoclient/shanchu.svg" class="SvgImg" />
</span>
</a-popconfirm>
</a-tooltip>
</div>
<div>
<a-dropdown>
<template #overlay>
<a-menu>
<a-menu-item>现舱</a-menu-item>
</a-menu>
</template>
<a-button type="link">
<span style="font-size: 11px" class="iconfont icon-qudiaozhuanli"></span>
现舱
<span class="iconfont icon-30jiantouxiangxiafill"></span>
</a-button>
</a-dropdown>
</div>
</template>
<template v-slot:bodyCell="{ column, record }">
<template v-if="column.dataIndex == 'statusText'">
<span v-if="record.status == 0" class="ds-blue-tag">
{{ record.statusText }}</span>
<span v-else-if="record.status == 1" class="ds-green-tag">{{
record.statusText
}}</span>
<span v-else-if="/^2|3$/.test(record.status)" class="ds-orange-tag">{{
record.statusText
}}</span>
<span v-else-if="/^4|5$/.test(record.status)" class="ds-red-tag">{{
record.statusText
}}</span>
<span v-else class="ds-purple-tag">{{ record.statusText }}</span>
</template>
</template>
</BasicTable>
</div>
<div style="padding-left: 20px;">
<a-spin :spinning="loading">
<a-tabs @change="tabChange" v-model:activeKey="activeKey">
<a-tab-pane :key="0" tab="发票明细"></a-tab-pane>
<a-tab-pane :key="1" tab="费用明细"></a-tab-pane>
<a-tab-pane :key="2" tab="附件"></a-tab-pane>
</a-tabs>
<div style="display: flex;" v-if="activeKey == 0">
<div class="left">
<BasicTable class="ds-mini-table-detail pay-table" @register="registerTable2">
</BasicTable>
</div>
<div class="right">
<div style="font-size: 12px;color: black;font-weight: bold;margin-bottom: 10px">票面信息</div>
<div class="row">
<span class="text">发票抬头</span>
<span class="bold">{{ feeData.invoiceHeader }}</span>
</div>
<div class="row">
<span class="text">纳税人识别号</span>
<span class="bold">{{ feeData.taxID }}</span>
</div>
<div class="row">
<span class="text">地址电话</span>
<span class="bold">{{ feeData.customerAddTel }}</span>
</div>
<div class="row">
<span class="text">RMB开户行/账号</span>
<span class="bold">{{ feeData.customerBankName }}</span>
</div>
<div class="row" style="border-bottom: 1px solid #ebebeb;padding-bottom: 10px;">
<span class="text">USD开户行/账号</span>
<span class="bold">{{ feeData.usdCustomerBankName }}</span>
</div>
<div class="row">
<div style="margin-right: 30px">
<span class="text">申请人</span>
<span class="bold">{{ feeData.createByName }}</span>
</div>
<div>
<span class="text">申请开票日期</span>
<span class="bold">{{ feeData.invoiceDate }}</span>
</div>
</div>
<div class="row">
<div style="margin-right: 30px">
<span class="text">所属分部</span>
<span class="bold">{{ feeData.saleDeptName }}</span>
</div>
<div>
<span class="text">代开客户</span>
<span class="bold">{{ feeData.autualCustomerName }}</span>
</div>
</div>
<div class="row">
<div>
<span class="text">客户名称</span>
<span class="bold">{{ feeData.customerName }}</span>
</div>
</div>
</div>
</div>
<div style="display: flex;" v-if="activeKey == 1">
<div class="left-fee">
<BasicTable @register="registerTable3">
<template v-slot:bodyCell="{ column, record }">
<template v-if="column.key === 'feeType'">
<span v-if="record.feeType == 1"></span>
<span v-if="record.feeType == 2"></span>
</template>
</template>
</BasicTable>
</div>
<div class="right-fee">
<BasicTable @register="registerTable4">
<template v-slot:bodyCell="{ column, record }">
<template v-if="column.key === 'feeType'">
<span v-if="record.feeType == 1"></span>
<span v-if="record.feeType == 2"></span>
</template>
</template>
</BasicTable>
</div>
</div>
<div style="display: flex;" v-if="activeKey == 2">
<a-table size="small" :pagination="false" rowKey="id" :columns="columnsFile" :data-source="fileData"
bordered>
<template v-slot:bodyCell="{ column, record }">
<template v-if="column.dataIndex == 'fileName'">
<a @click="download(record)">{{ record.fileName }}</a>
</template>
<template v-if="column.dataIndex == 'caozuo'">
<a @click="lookFile(record)"></a>
</template>
</template>
</a-table>
</div>
</a-spin>
</div>
<a-modal width="600px" @cancel="refuseFlag = false" @ok="sureRefuse" :visible="refuseFlag" title="驳回原因">
<a-textarea v-model:value="remark" :auto-size="{ minRows: 4, maxRows: 7 }" />
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, defineExpose, computed } from 'vue'
import { GetList, InvoiceApplicationGet, Audit, GetOpFileList } from './api.js'
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { formatParams } from '/@/hooks/web/common'
import { columns, searchFormSchema, detailColumns, feeColumns, feeColumnsSum } from './columns'
import { useMessage } from '/@/hooks/web/useMessage'
const { createMessage } = useMessage()
const [registerTable, { reload, getPaginationRef, getSelectRows, getRawDataSource }] = useTable({
maxHeight: 300,
api: async (p) => {
const res: API.DataResult = await GetList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
},
//
beforeFetch: (p) => {
let data = formatParams(p)
data.OtherQueryCondition = p.status
return data
},
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
useAdvancedSearch: true,
},
isTreeTable: false,
pagination: true,
striped: true,
useSearchForm: true,
showTableSetting: true,
bordered: true,
showIndexColumn: true,
indexColumnProps: {
width: 60,
},
canResize: true,
immediate: true,
})
const [registerTable2, { getSelectRows: getSelectRows2, clearSelectedRowKeys: clearSelectedRowKeys2, setTableData }] = useTable({
columns: detailColumns,
isTreeTable: false,
pagination: false,
showIndexColumn: false,
bordered: true,
canResize: false,
showSummary: true,
summaryFunc(param) {
const sums = {} as any
//
const columns = detailColumns
columns.forEach(column => {
if (['taxAmount', 'amount'].includes(column.dataIndex)) {
// 0
sums[column.dataIndex] = 0
//
param.forEach(row => {
if (!isNaN(row[column.dataIndex])) {
console.log(row[column.dataIndex])
sums[column.dataIndex] += Number(row[column.dataIndex])
}
})
}
})
sums.taxAmount = (Number(sums.taxAmount)).toFixed(2)
sums.amount = (Number(sums.amount)).toFixed(2)
sums.name = '合计'
//
return [sums]
}
})
const feeList = ref([])
const [registerTable3, { setTableData: setTableDataFee }] = useTable({
columns: feeColumns,
useSearchForm: false,
showIndexColumn: false,
pagination: false,
showTableSetting: false,
striped: true,
rowKey: 'id',
bordered: true,
canResize: true,
immediate: false,
})
const [registerTable4, { setTableData: setTableDataFeeSum }] = useTable({
columns: feeColumnsSum,
useSearchForm: false,
showIndexColumn: false,
pagination: false,
showTableSetting: false,
striped: true,
rowKey: 'id',
bordered: true,
canResize: true,
immediate: false,
})
const columnsFile = [
{
title: '文件名称',
width: 150,
dataIndex: 'fileName',
},
{
title: '上传日期',
width: 150,
dataIndex: 'createTime',
},
{
title: '上传者',
width: 150,
dataIndex: 'createUserName',
},
{
title: '操作',
width: 150,
dataIndex: 'caozuo',
},
]
const activeKey = ref(0)
const feeData = ref({}) as any
const loading = ref(false)
const fileData = ref([]) as any
const remark = ref('')
function download(item) {
DownloadOpFile({ id: item.id }).then(res => {
const pdfUrl = window.URL.createObjectURL(new Blob([res.data], { type: 'application/txt;charset=utf-8' }))
const fname = item.fileName //
const link = document.createElement('a')
link.href = pdfUrl
link.setAttribute('download', fname)
document.body.appendChild(link)
link.click()
})
}
function handleClick(row) {
loading.value = true
InvoiceApplicationGet({ id: row.id }).then(res => {
if (res.succeeded) {
feeData.value = res.data
setTableData(res.data.invoiceDetails)
//
}
loading.value = false
})
getfileList(row.id)
}
function tabChange(val) {
if (val == 1) {
setTimeout(() => {
setTableDataFee(feeData.value.details)
setTableDataFeeSum(feeData.value.summaryItems)
}, 100)
}
if (val == 0) {
setTimeout(() => {
setTableData(feeData.value.invoiceDetails)
}, 100)
}
}
const getfileList = (id) => {
GetOpFileList({ id: id }).then(res => {
res.data.forEach(item => {
if (item.createTime) {
item.createTime = new Date(item.createTime)
item.createTime = item.createTime.getFullYear() + '-' + (item.createTime.getMonth() + 1) + '-' + (item.createTime.getDate())
}
item['type'] = item?.filePath?.split('.')[1]
fileData.value = res.data
})
if (res.data.length == 0) {
fileData.value = []
}
}).catch(() => {
})
}
function applySuccess() {
let ids = []
ids = getSelectRows().map((item) => {
return item.id
})
const data = {
result: 1,
ids: ids,
businessType: 1
}
if (ids.length == 0) {
createMessage.error('请选择数据')
return false
}
Audit(data).then(res => {
if (res.succeeded) {
createMessage.success('操作成功')
reload()
}
})
}
const refuseFlag = ref(false)
function refuse() {
let ids = []
ids = getSelectRows().map((item) => {
return item.id
})
if (ids.length == 0) {
createMessage.error('请选择数据')
return false
}
refuseFlag.value = true
}
function sureRefuse() {
let ids = []
ids = getSelectRows().map((item) => {
return item.id
})
const data = {
result: 2,
remark: remark.value,
ids: ids,
businessType: 1
}
Audit(data).then(res => {
if (res.succeeded) {
createMessage.success('操作成功')
reload()
refuseFlag.value = false
}
})
}
</script>
<style lang="less" scoped>
/deep/ .ant-table-pagination.ant-pagination {
border-bottom: 1px solid #ebebeb;
margin-bottom: 0px;
padding-bottom: 10px;
}
.left {
width: 58%;
margin-right: 1%;
padding-right: 10px;
border-right: 1px solid #ebebeb;
}
.right {
width: 40%;
padding-top: 5px;
font-size: 12px;
}
.left-fee {
width: 78%;
margin-right: 1%;
padding-right: 10px;
border-right: 1px solid #ebebeb;
}
.right-fee {
width: 21%;
padding-top: 5px;
font-size: 12px;
}
.row {
margin-bottom: 10px;
display: flex;
.text {
color: #7a8798;
display: inline-block;
}
.bold {
color: black;
display: inline-block;
width: 200px;
}
}
.receive-table,
.pay-table {
flex: 1;
th::before {
height: 0 !important;
}
/deep/ .ant-table-footer {
/deep/ .ant-table-measure-row {
display: none;
}
/deep/ .ant-table-row-level-0 {
height: 26px !important;
padding-left: 50px;
td {
padding: 5px 6px !important;
font-size: 14px;
font-weight: 600 !important;
}
}
}
}
.fee-table {
/deep/ .ant-table-body {
min-height: calc(50vh - 210px);
}
}
/deep/ .ant-divider-vertical {
height: 20px;
margin: 0 10px;
background: #eeeeee;
}
/deep/ .vben-basic-table .ant-table-footer td {
padding: 0px 10px !important;
}
.SvgImg {
width: 18px;
height: 18px;
margin: 6.8px;
}
.ds-h-aciton-btns-fee {
display: flex;
align-items: center;
height: 38px;
padding-right: 10px;
border-right: 1px solid rgb(194, 188, 188);
.ds-action-svg-btn {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 2px;
margin-right: 8px;
cursor: pointer;
.next {
transform: rotate(180deg);
}
}
.ds-action-svg-btn:hover {
box-shadow: 0px 2px 4px #cad1db;
}
.vben-svg-icon {
margin: 6.8px;
}
}
</style>
<style lang="less"></style>
Loading…
Cancel
Save