费用申请

szh-new
lijingjia 5 months ago
parent 167defa3ed
commit 29f6965685

@ -13,6 +13,12 @@ import { getDictOption } from '/@/utils/dictUtil'
const customTypeDict = ref([])
// 账号类型下拉数据
const accountTypeDict = ref([])
getDictOption('account_type').then(data => {
accountTypeDict.value = data
})
getDictOption('djy_cust_prop').then(data => {
customTypeDict.value = data
})
// 客户名称下拉框数据
const companyDict = ref([])
export const columns: BasicColumn[] = [
@ -76,9 +82,6 @@ export const formSchema: FormSchema[] = [
component: 'Select',
colProps: { span: 12 },
componentProps: () => {
getDictOption('account_type').then(data => {
accountTypeDict.value = data
})
return {
options: accountTypeDict.value,
allowClear: true,
@ -100,12 +103,8 @@ export const formSchema: FormSchema[] = [
field: 'customerType',
label: '客户类型',
component: 'Select',
required: true,
colProps: { span: 12 },
componentProps: () => {
getDictOption('djy_cust_prop').then(data => {
customTypeDict.value = data
})
return {
options: customTypeDict.value,
allowClear: true,
@ -129,7 +128,6 @@ export const formSchema: FormSchema[] = [
{
field: 'customerName',
label: '客户名称',
required: true,
component: 'Select',
colProps: { span: 12 },
componentProps: ({ formModel }) => {

@ -9,6 +9,12 @@ import { BasicColumn, FormSchema } from '/@/components/Table'
import { getDictOption } from '/@/utils/dictUtil'
// 业务种类字典
const opTypeDict = ref([])
getDictOption('business_type').then(data => {
data.forEach(res => {
res.value = String(res.value)
})
opTypeDict.value = data
})
export const columns: BasicColumn[] = [
{
title: '模版名称',
@ -100,12 +106,6 @@ export const formSchema: FormSchema[] = [
required: true,
colProps: { span: 8 },
componentProps: ({ formActionType }) => {
getDictOption('business_type').then(data => {
data.forEach(res => {
res.value = String(res.value)
})
opTypeDict.value = data
})
return {
options: opTypeDict.value,
allowClear: true,

@ -12,7 +12,12 @@ enum Api {
info = '/feeApi/FeeCurrency/GetFeeCurrencyInfo',
GetBizList = '/feeApi/PaymentApplication/GetBizList',
Save = '/feeApi/PaymentApplication/Save',
Get = '/feeApi/PaymentApplication//Get'
Get = '/feeApi/PaymentApplication/Get',
GetExchangeRate = '/feeApi/FeeCurrencyExchange/GetExchangeRate',
BizSave = '/feeApi/PaymentApplication/BizSave',
Delete = '/feeApi/PaymentApplication/Delete',
ApplyAudit = '/feeApi/PaymentApplication/ApplyAudit',
Withdraw = '/feeApi/PaymentApplication/Withdraw'
}
// 列表 (Auth)
export function GetList(data: PageRequest) {
@ -61,4 +66,44 @@ export function Get(query) {
method: 'get',
params: query
})
}
// 根据两种币别计算汇率接口
export function GetExchangeRate(query) {
return request<DataResult>({
url: Api.GetExchangeRate,
method: 'get',
params: query
})
}
// 按业务申请
export function BizSave(data: PageRequest) {
return request<DataResult>({
url: Api.BizSave,
method: 'post',
data
})
}
// 删除申请单
export function Delete(data: PageRequest) {
return request<DataResult>({
url: Api.Delete,
method: 'post',
data
})
}
// 申请单提交审核
export function ApplyAudit(data: PageRequest) {
return request<DataResult>({
url: Api.ApplyAudit,
method: 'post',
data
})
}
// 撤销审批
export function Withdraw(data: PageRequest) {
return request<DataResult>({
url: Api.Withdraw,
method: 'post',
data
})
}

@ -29,7 +29,7 @@ export const columns: BasicColumn[] = [
},
{
title: '状态',
dataIndex: 'status',
dataIndex: 'statusText',
width: 100,
align: 'left'
},

@ -11,25 +11,35 @@
<div class="nav">
<i class="iconfont icon-jiahao2fill"></i>入账申请加入
</div>
<div class="nav"
><i class="iconfont icon-fuzhi"></i>提交审核</div
<a-popconfirm
title="确定提交选中数据?"
ok-text="是"
cancel-text="否"
@confirm="submit"
>
<div class="nav"
><i class="iconfont icon-fuzhi1"></i>撤销提交</div
<div class="nav"><i class="iconfont icon-fuzhi"></i>提交审核</div>
</a-popconfirm>
<a-popconfirm
title="确定撤销提交?"
ok-text="是"
cancel-text="否"
@confirm="cancel"
>
<a-popconfirm
title="确定删除当前选中订舱?"
ok-text="是"
cancel-text="否"
@confirm="removeMoreFun"
>
<div class="nav"><i class="iconfont icon-shanchu2"></i>删除</div>
</a-popconfirm>
<div class="nav"><i class="iconfont icon-xiaopiaodayin"></i>打印</div>
<div class="nav">
<i class="iconfont icon-shishijifei"></i>导出Excel
</div>
<div class="nav"><i class="iconfont icon-fuzhi"></i>撤销提交</div>
</a-popconfirm>
<a-popconfirm
title="确定删除当前选中数据?"
ok-text="是"
cancel-text="否"
@confirm="removeMoreFun"
>
<div class="nav"><i class="iconfont icon-shanchu2"></i>删除</div>
</a-popconfirm>
<div class="nav"><i class="iconfont icon-xiaopiaodayin"></i>打印</div>
<div class="nav">
<i class="iconfont icon-shishijifei"></i>导出Excel
</div>
</div>
</template>
<script lang="ts" setup>
@ -38,6 +48,7 @@
import { useMessage } from '/@/hooks/web/useMessage'
import { useRouter } from 'vue-router'
import { useModal } from '/@/components/Modal'
import { Delete, ApplyAudit, Withdraw } from '../api'
const router = useRouter()
const { createMessage } = useMessage()
const go = useGo()
@ -73,12 +84,77 @@
function removeMoreFun() {
const select = props.selectRow()
if (select.length === 0) {
createMessage.warning('请选择操作订单!')
createMessage.warning('请选择操作数据!')
return false
}
for(let i = 0; i < select.length; i++) {
if (select[i].status !== 0) {
return createMessage.warning('仅允许删除未提交状态的数据!')
}
}
const ids = select.map((item) => {
return item.id
})
const postData = {
ids
}
Delete(postData).then(res => {
if (res.succeeded) {
createMessage.success('删除成功!')
props.reload()
}
})
}
//
const submit = () => {
const select = props.selectRow()
if (select.length === 0) {
createMessage.warning('请选择操作数据!')
return false
}
const removeArr = select.map((item) => {
for(let i = 0; i < select.length; i++) {
if (select[i].status !== 0) {
return createMessage.warning('仅允许未提交状态的数据进行提交审核!')
}
}
const ids = select.map((item) => {
return item.id
})
const postData = {
ids
}
ApplyAudit(postData).then(res => {
if (res.succeeded) {
createMessage.success('提交成功!')
props.reload()
}
console.log(res)
})
}
//
const cancel = () => {
const select = props.selectRow()
if (select.length === 0) {
createMessage.warning('请选择操作数据!')
return false
}
for(let i = 0; i < select.length; i++) {
if (select[i].status !== 1) {
return createMessage.warning('仅允许撤销状态为提交审核的数据!')
}
}
const ids = select.map((item) => {
return item.id
})
const postData = {
ids
}
Withdraw(postData).then(res => {
if (res.succeeded) {
createMessage.success('撤销成功!')
props.reload()
}
})
}
</script>

@ -7,8 +7,11 @@ import { ref, h, ComponentOptions, resolveComponent } from 'vue'
import { BasicColumn, FormSchema } from '/@/components/Table'
import { useOptionsStore } from '/@/store/modules/options'
const optionsStore = useOptionsStore()
import { useRoute } from 'vue-router'
const route = useRoute()
// 引入字典数据
import { getDictOption } from '/@/utils/dictUtil'
import { placeholderSign } from 'element-plus/es/components/table-v2/src/private'
// 业务表格列
export const businessColumns: BasicColumn[] = [
@ -189,6 +192,12 @@ export const businessColumns: BasicColumn[] = [
]
export const formSchema: FormSchema[] = [
{
field: 'id',
label: '申请编号',
component: 'Input',
show: false
},
{
field: 'applicationNO',
label: '申请编号',
@ -226,7 +235,6 @@ export const formSchema: FormSchema[] = [
labelField: 'shortName',
valueField: 'id',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
@ -266,7 +274,13 @@ export const formSchema: FormSchema[] = [
label: '申请日期',
component: 'DatePicker',
dynamicDisabled: false,
colProps: { span: 3 }
colProps: { span: 3 },
componentProps: {
showTime: true,
allowClear: true,
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
},
},
{
field: 'currency',
@ -274,12 +288,14 @@ export const formSchema: FormSchema[] = [
component: 'ApiSelect',
required: false,
dynamicDisabled: false,
defaultValue: null,
colProps: { span: 3 },
componentProps: () => {
return {
option: optionsStore.getOptionsByCode('GetFeeCurrencySelectList'),
labelField: 'name',
valueField: 'codeName',
placeholder: '原币申请',
resultField: 'data',
immediate: false,
filterOption: (input: string, option: any) => {
@ -355,7 +371,13 @@ export const formSchema: FormSchema[] = [
label: '申请支付日期',
component: 'DatePicker',
dynamicDisabled: false,
colProps: { span: 3 }
colProps: { span: 3 },
componentProps: {
showTime: true,
allowClear: true,
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
},
},
// {
// field: 'createBy',
@ -374,7 +396,7 @@ export const formSchema: FormSchema[] = [
]
export const searchFormSchema: FormSchema[] = [
{
label: '结算单位',
label: '结算对象',
field: 'customerId',
component: 'ApiSelect',
dynamicDisabled: false,
@ -382,9 +404,8 @@ export const searchFormSchema: FormSchema[] = [
componentProps: () => {
return {
option: optionsStore.getOptionsByCode('GetClientListByCode'),
immediate: false,
labelField: 'shortName',
valueField: 'codeName',
valueField: 'id',
resultField: 'data',
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0

@ -5,37 +5,45 @@
-->
<template>
<div class="ds-bus-table">
<BasicTable
:canRowSelect="true"
:scroll="{ x: '100%', y: 188 }"
:row-selection="{ selectedRowKeys: state.historyRowKeys, onChange: historyChange }"
rowKey="id"
@register="registerTable"
@row-click="onRowClick"
>
<template #toolbar>
<a-button type="link" @click="addInfos"></a-button>
</template>
</BasicTable>
<div class="info">
<div>
<a-button @click="save" type="link">添加申请费用明细</a-button>
<a-spin :spinning="loading">
<BasicTable
:canRowSelect="true"
:scroll="{ x: '100%', y: 188 }"
:row-selection="{ selectedRowKeys: state.historyRowKeys, onChange: historyChange }"
rowKey="id"
@register="registerTable"
@row-click="onRowClick"
>
<template #toolbar>
<a-button type="link" @click="addInfos"></a-button>
</template>
</BasicTable>
<div class="info">
<div>
<a-button @click="save" type="link">增加申请费用明细</a-button>
</div>
<feeTable
ref="feeTabel"
></feeTable>
</div>
<feeTable
ref="feeTabel"
></feeTable>
</div>
</a-spin>
<!-- 汇率换算组件 -->
<ExchangeRate
ref="exchangeRate"
@submit="saveExchangeRate"
></ExchangeRate>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, reactive, watch, defineExpose, defineProps, defineEmits } from 'vue'
import { onMounted, ref, reactive, watch, defineExpose, defineProps, defineEmits, h } from 'vue'
import { BasicTable, useTable } from '/@/components/Table'
import { GetBizList } from '../../api'
import { GetBizList, BizSave } from '../../api'
import { businessColumns, searchFormSchema } from '../columns'
import feeTable from '/@/components/CostEntry/components/feeTable.vue'
import ExchangeRate from './exchangeRate.vue'
//
import { useMessage } from '/@/hooks/web/useMessage'
const emit = defineEmits(['save'])
const emit = defineEmits(['save', 'refresh'])
const { createMessage } = useMessage()
const props = defineProps({
//
@ -47,7 +55,8 @@
type: Function
}
})
const [registerTable, { reload, getForm, getPaginationRef, getSelectRows, setSelectedRows }] = useTable({
const loading = ref(false)
const [registerTable, { reload, getForm, getPaginationRef, getSelectRows, setSelectedRows, getDataSource }] = useTable({
api: async (p) => {
const res = await GetBizList(p)
if (res?.data?.length) state.historyRowKeys = [res.data[0].id]
@ -59,6 +68,7 @@
beforeFetch: () => {
var currentPageInfo: any = getPaginationRef()
var data = getForm().getFieldsValue()
console.log(data)
const postParam = {
queryCondition: '',
pageCondition: {
@ -68,10 +78,10 @@
},
}
let condition: API.ConditionItem[] = []
if (!!data.customerNo) {
if (!!data.customerId) {
condition.push({
FieldName: 'customerNo',
FieldValue: data.customerNo,
FieldName: 'customerId',
FieldValue: data.customerId,
ConditionalType: 1
})
}
@ -134,6 +144,17 @@
const allFeeData = {}
const feeTabel = ref(null)
const historyChange = async (v) => {
if (v.length > 1) {
const a = getDataSource().filter(item => {
return item.id == v[0]
})[0]
const b = getDataSource().filter(item => {
return item.id == v[v.length - 1]
})[0]
if (a.customerId != b.customerId) {
return createMessage.warning('请选择结算对象一致的数据!')
}
}
state.historyRowKeys = v
}
//
@ -144,16 +165,75 @@
const feeData = () => {
return feeTabel.value.selectfeeData
}
//
const feeTableData = ref([])
//
const exchangeRate = ref(null)
//
const save = () => {
const data = feeTabel.value.selectfeeData
emit('save', data)
//
feeTableData.value = feeTabel.value.selectfeeData
if (feeTableData.value.length == 0) {
return createMessage.warning('请选择要申请的费用明细!')
}
//
const customer = props.formData?.customerId
console.log(customer)
let cflag = true
//
const currency = props.formData?.currency
//
const mData = getSelectRows()
mData.forEach(item => {
if (item.customerId == customer) {
cflag = false
}
})
if (customer && cflag) {
//
return createMessage.warning('结算对象与付费申请客户不一致,不能添加此费用明细!')
}
if (currency) {
//
let currencyList = []
//
feeTableData.value.forEach((item, index) => {
if (item.currency != currency) {
currencyList.push({
currency: item.currency,
feeType: item.feeType,
//
value: null,
//
value1: null
})
}
})
currencyList = Array.from(new Set(currencyList.map(item => item.currency))).map(currency => {
return currencyList.find(item => item.currency === currency)
})
console.log(currencyList)
//
exchangeRate.value.init(currency, currencyList)
} else {
//
emit('save', feeTableData.value)
}
}
//
const saveExchangeRate = (list) => {
feeTableData.value.forEach(row => {
list.forEach(item => {
if (row.currency == item.currency) {
row.exchangeRate = item.value
}
})
})
emit('save', feeTableData.value)
}
//
const addInfos = () => {
const selectRows = getSelectRows()
console.log(selectRows)
// console.log(props.formData.currency)
return
if (props.formData.customerId) {
let flag = false
selectRows.forEach(item => {
@ -164,25 +244,61 @@
if (!flag) {
return createMessage.warning('没有选择要添加的业务!')
}
selectRows
} else {
if (state.historyRowKeys.length == 0 ) {
return createMessage.warning('没有选择要添加的业务!')
}
}
console.log(allFeeData)
//
let feeList = []
for(var key in allFeeData) {
feeList = [...feeList, ...allFeeData[key]]
}
console.log(props.formData)
feeList.forEach(item => {
if (props.formData.currency && props.formData.currency != item.currency) {
if (!props.formData.currency) {
//
const postData = {
description: '按业务增加添加费用明细',
application: {
id: 0,
customerId: selectRows[0]?.customerId
},
items: [{
id: selectRows[0]?.id,
businessType: selectRows[0]?.businessType
}]
}
})
loading.value = true
BizSave(postData).then(res => {
loading.value = false
if (res.succeeded) {
createMessage.success('增加成功!')
emit('refresh')
}
})
} else {
//
//
let feeList = []
for(var key in allFeeData) {
feeList = [...feeList, ...allFeeData[key]]
}
//
let currencyList = []
//
feeList.forEach((item, index) => {
if (item.currency != props.formData.currency) {
currencyList.push({
currency: item.currency,
feeType: item.feeType,
//
value: null,
//
value1: null
})
}
})
currencyList = Array.from(new Set(currencyList.map(item => item.currency))).map(currency => {
return currencyList.find(item => item.currency === currency)
})
//
feeTableData.value = feeList
exchangeRate.value.init(props.formData.currency, currencyList)
}
}
watch(
() => state.historyRowKeys, (v, old) => {
@ -218,9 +334,17 @@
}
})
onMounted(() => {
//
reload()
onMounted(async () => {
//
if (props.formData?.customerId) {
console.log(props.formData.customerId)
await getForm().setFieldsValue({ 'customerId': props.formData.customerId })
//
reload()
} else {
//
reload()
}
})
defineExpose({
feeData

@ -0,0 +1,89 @@
<!--
* @Description: 操作管理 -> 付费申请 -> 汇率换算组件
* @Author: lijj
* @Date: 2024-06-20 11:54:04
-->
<template>
<div>
<a-modal class="ds-exchange-rate" v-model:visible="visible" title="币别汇率折算" cancelText="关闭" @ok="handleOk">
<div v-for="(item, index) in c2" :key="'cur' + index">
<p class="flex">
<span class="unit">1{{ c1 }} =</span>
<a-input-number
v-model:value="item.value"
:min="0.000001"
:max="99999999"
:step="0.000001"
string-mode
:precision="6"
@change="calc1($event, item)"
/>
{{ item.currency }}
</p>
<p class="flex">
<span class="unit">1{{ item.currency }} =</span>
<a-input-number
v-model:value="item.value1"
:min="0.000001"
:max="99999999"
:step="0.000001"
:precision="6"
string-mode
@change="calc2($event, item)"
/>
{{ c1 }}
</p>
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, defineEmits, defineProps, watch, defineExpose } from 'vue'
import { GetExchangeRate } from '../../api'
const emit = defineEmits(['submit'])
const visible = ref(false)
const value = ref(0)
const value1 = ref(0)
const handleOk = () => {
visible.value = false
emit('submit', c2.value)
}
//
const c1 = ref()
//
const c2 = ref([])
const init = (currency, list) => {
visible.value = true
c1.value = currency
c2.value = list
c2.value.forEach(item => {
GetExchangeRate({ currencyFrom: currency, currencyTo: item.currency, feeType: item.feeType }).then(res => {
item.value = res.data.rate
item.value1 = res.data.reverseRate
})
})
}
const calc1 = (e, item) => {
item.value1 = (1 / e).toFixed(6)
}
const calc2 = (e, item) => {
item.value = (1 / e).toFixed(6)
}
defineExpose({
init
})
</script>
<style lang="less">
.ds-exchange-rate {
.unit {
display: inline-block;
width: 66px;
}
.ant-input-number {
position: relative;
top: -4px;
margin-right: 5px;
}
}
</style>

@ -6,8 +6,8 @@
<template>
<div class="ds-pay-apply-detail ds-detail-box">
<a-spin :spinning="dloading">
<div>
<a-button @click="save"></a-button>
<div class="ds-card">
<a-button @click="save" type="link">保存</a-button>
</div>
<!-- 表单区域 -->
<div class="form-area">
@ -32,10 +32,12 @@
<a-spin :spinning="loading">
<!-- 业务表格 -->
<BusinessTable
v-if="visible"
ref="busTable"
:formData="getFieldsValue()"
:setFieldsValue="setFieldsValue"
@save="save"
@refresh="refresh"
></BusinessTable>
</a-spin>
</a-modal>
@ -129,15 +131,26 @@
visible.value = true
}
const applyInfo = ref(null)
//
const refresh = () => {
visible.value = false
init()
}
//
const save = async (feeInfo) => {
const postData = await validate()
postData['details'] = feeInfo
if (feeInfo.length) {
postData['details'] = [...feeData.value, ...feeInfo]
} else {
postData['details'] = feeData.value
}
loading.value = true
Save(postData).then(res => {
console.log(res)
loading.value = false
visible.value = false
applyInfo.value.reload()
init()
})
}
//
@ -147,7 +160,10 @@
dloading.value = true
Get({ id }).then(res => {
dloading.value = false
setFieldsValue(res.data)
console.log(res.data)
setFieldsValue({
...res.data
})
feeData.value = res.data.details
})
}

@ -87,7 +87,6 @@
bordered: true,
showIndexColumn: true,
canResize: false,
rowSelection: { type: 'checkbox' },
immediate: false
})
const copyNo = (e, v) => {

Loading…
Cancel
Save