费用管理-费用模版

szh-new
lijingjia 7 months ago
parent d7df7113a4
commit 15a90edc7f

@ -28,7 +28,7 @@ export const columns: BasicColumn[] = [
}, },
{ {
title: '标准', title: '标准',
dataIndex: 'unit', dataIndex: 'unitName',
width: 150 width: 150
}, },
{ {

@ -25,21 +25,28 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineComponent, onMounted, ref } from 'vue' import { onMounted } from 'vue'
import { BasicTable, useTable, TableAction } from '/@/components/Table' import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getFeeCustTemplateDetailList } from './api' import { getFeeCustTemplateDetailList } from './api'
import { useModal } from '/@/components/Modal' import { useModal } from '/@/components/Modal'
import Modal from './components/Modal.vue' import Modal from './components/Modal.vue'
import { columns, searchFormSchema } from './columns' import { columns, searchFormSchema } from './columns'
const dictOptions = ref<any[]>([]) //
import { getDictOption } from '/@/utils/dictUtil'
const [registerModal, { openModal }] = useModal() const [registerModal, { openModal }] = useModal()
const [registerPermissionModal, { openModal: openPermissionModal }] = useModal()
const [registerTable, { reload, getForm, getPaginationRef }] = useTable({ const [registerTable, { reload, getForm, getPaginationRef }] = useTable({
title: '往来单位固定费用', title: '往来单位固定费用',
// api: getSysDictTypeList, // api: getSysDictTypeList,
api: async (p) => { api: async (p) => {
const res: API.DataResult = await getFeeCustTemplateDetailList(p) const res: API.DataResult = await getFeeCustTemplateDetailList(p)
// console.log(items); const dicts = await getDictOption('fee_unit')
res.data.forEach(row => {
dicts.forEach(item => {
if (row.unit == item.value) {
row.unitName = item.label
}
})
})
return new Promise((resolve) => { return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count }) resolve({ data: [...res.data], total: res.count })
}) })
@ -108,9 +115,6 @@
isUpdate: true, isUpdate: true,
}) })
} }
function handleDelete(record: Recordable) {
console.log(record)
}
onMounted(() => { onMounted(() => {
// //

@ -16,12 +16,22 @@ export const columns: BasicColumn[] = [
{ {
title: '开始日期', title: '开始日期',
dataIndex: 'startDate', dataIndex: 'startDate',
width: 130 width: 130,
customRender: ({ text }) => {
if (text) {
return text.split(' ')[0]
}
}
}, },
{ {
title: '结束日期', title: '结束日期',
dataIndex: 'endDate', dataIndex: 'endDate',
width: 130 width: 130,
customRender: ({ text }) => {
if (text) {
return text.split(' ')[0]
}
}
}, },
{ {
title: '应收汇率', title: '应收汇率',
@ -46,7 +56,12 @@ export const columns: BasicColumn[] = [
{ {
title: '录入时间', title: '录入时间',
dataIndex: 'createTime', dataIndex: 'createTime',
width: 120 width: 120,
customRender: ({ text }) => {
if (text) {
return text.split(' ')[0]
}
}
}, },
{ {
title: '备注', title: '备注',

@ -7,12 +7,14 @@
import { request } from '/@/utils/request' import { request } from '/@/utils/request'
import { DataResult, PageRequest } from '/@/api/model/baseModel' import { DataResult, PageRequest } from '/@/api/model/baseModel'
enum Api { enum Api {
list = '/feeApi/FeeCurrency/GetFeeCurrencyList', list = '/feeApi/FeeTemplate/GetFeeTemplateList',
edit = '/feeApi/FeeCurrency/EditFeeCurrency', edit = '/feeApi/FeeTemplate/EditFeeTemplate',
info = '/feeApi/FeeCurrency/GetFeeCurrencyInfo' info = '/feeApi/FeeTemplate/GetFeeTemplateInfo',
detailList = '/feeApi/FeeTemplateDetail/GetFeeTemplateDetailList',
detailDelete = '/feeApi/FeeTemplateDetail/BatchDelFeeTemplateDetail'
} }
// 列表 (Auth) // 列表 (Auth)
export function getFeeCurrencyList(data: PageRequest) { export function GetFeeTemplateList(data: PageRequest) {
return request<DataResult>({ return request<DataResult>({
url: Api.list, url: Api.list,
method: 'post', method: 'post',
@ -20,7 +22,7 @@ export function getFeeCurrencyList(data: PageRequest) {
}) })
} }
// 编辑 (Auth) // 编辑 (Auth)
export function editFeeCurrency(data: PageRequest) { export function EditFeeTemplate(data: PageRequest) {
return request<DataResult>({ return request<DataResult>({
url: Api.edit, url: Api.edit,
method: 'post', method: 'post',
@ -28,10 +30,26 @@ export function editFeeCurrency(data: PageRequest) {
}) })
} }
// 详情 (Auth) // 详情 (Auth)
export function getFeeCurrencyInfo(query) { export function GetFeeTemplateInfo(query) {
return request<DataResult>({ return request<DataResult>({
url: Api.info, url: Api.info,
method: 'get', method: 'get',
params: query params: query
}) })
} }
// 明细列表
export function GetFeeTemplateDetailList(data: PageRequest) {
return request<DataResult>({
url: Api.detailList,
method: 'post',
data
})
}
// 明细删除 (Auth)
export function BatchDelFeeTemplateDetail(data: PageRequest) {
return request<DataResult>({
url: Api.detailDelete,
method: 'post',
data: data
})
}

@ -3,7 +3,12 @@
* @Author: lijj * @Author: lijj
* @Date: 2024-04-25 15:48:33 * @Date: 2024-04-25 15:48:33
*/ */
import { ref } from 'vue'
import { BasicColumn, FormSchema } from '/@/components/Table' import { BasicColumn, FormSchema } from '/@/components/Table'
// 引入字典数据
import { getDictOption } from '/@/utils/dictUtil'
// 业务种类字典
const opTypeDict = ref([])
export const columns: BasicColumn[] = [ export const columns: BasicColumn[] = [
{ {
title: '模版名称', title: '模版名称',
@ -12,18 +17,34 @@ export const columns: BasicColumn[] = [
}, },
{ {
title: '业务种类', title: '业务种类',
dataIndex: 'opType', dataIndex: 'opTypeName',
width: 200 width: 200
}, },
{ {
title: '费用类别', title: '费用类别',
dataIndex: 'feeType', dataIndex: 'feeType',
width: 200 width: 200,
customRender: ({ text }) => {
if (text == 1) {
return '应收'
} else if (text == 2) {
return '应付'
} else {
return ''
}
}
}, },
{ {
title: '是否公共', title: '是否公共',
dataIndex: 'isPublic', dataIndex: 'isPublic',
width: 200 width: 200,
customRender: ({ text }) => {
if (text) {
return '是'
} else {
return '否'
}
}
}, },
{ {
title: '录入日期', title: '录入日期',
@ -77,7 +98,20 @@ export const formSchema: FormSchema[] = [
label: '业务种类', label: '业务种类',
component: 'Select', component: 'Select',
required: true, required: true,
colProps: { span: 8 } colProps: { span: 8 },
componentProps: ({ formActionType }) => {
getDictOption('business_type').then(data => {
opTypeDict.value = data
})
return {
options: opTypeDict.value,
allowClear: true,
showSearch: true,
filterOption: (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
}
}
}, },
{ {
field: 'feeType', field: 'feeType',
@ -97,6 +131,7 @@ export const formSchema: FormSchema[] = [
label: '是否公共', label: '是否公共',
component: 'RadioGroup', component: 'RadioGroup',
colProps: { span: 8 }, colProps: { span: 8 },
defaultValue: true,
componentProps: { componentProps: {
options: [ options: [
{ label: '是', value: true }, { label: '是', value: true },

@ -11,7 +11,7 @@
<!-- 费用模版表单 --> <!-- 费用模版表单 -->
<BasicForm @register="registerForm" /> <BasicForm @register="registerForm" />
<!-- 费用字段表格 --> <!-- 费用字段表格 -->
<FeeField></FeeField> <FeeField ref="feeField" :id="detailId"></FeeField>
<!--右下角按钮--> <!--右下角按钮-->
<template #footer> <template #footer>
<a-button <a-button
@ -53,23 +53,23 @@
// //
import { formSchema } from '../columns' import { formSchema } from '../columns'
// //
import { editFeeCurrency, getFeeCurrencyInfo } from '../api' import { EditFeeTemplate, GetFeeTemplateInfo } from '../api'
// //
import { useMessage } from '/@/hooks/web/useMessage' import { useMessage } from '/@/hooks/web/useMessage'
// Emits // Emits
const emit = defineEmits(['success', 'register']) const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true) const isUpdate = ref(true)
const detailId = ref()
// loading // loading
const loading = ref(false) const loading = ref(false)
const rowId = ref('') const rowId = ref('')
const { createMessage } = useMessage() const { createMessage } = useMessage()
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = const [registerForm, { resetFields, setFieldsValue, getFieldsValue, validate, updateSchema }] =
useForm({ useForm({
labelWidth: 100, labelWidth: 100,
schemas: formSchema, schemas: formSchema,
showActionButtonGroup: false, showActionButtonGroup: false,
}) })
const [registerModal, { setModalProps, closeModal, updateFormField }] = useModalInner(async (data) => { const [registerModal, { setModalProps, closeModal, updateFormField }] = useModalInner(async (data) => {
resetFields() resetFields()
setModalProps({ confirmLoading: false, loading: true }) setModalProps({ confirmLoading: false, loading: true })
@ -78,26 +78,30 @@
setModalProps({ confirmLoading: true }); setModalProps({ confirmLoading: true });
updateFormField(updateSchema) updateFormField(updateSchema)
rowId.value = data.record.id rowId.value = data.record.id
const res: API.DataResult = await getFeeCurrencyInfo({ id: unref(rowId) }) const res: API.DataResult = await GetFeeTemplateInfo({ id: unref(rowId) })
if (res.succeeded) { if (res.succeeded) {
setFieldsValue({ setFieldsValue({
...res.data, ...res.data,
}) })
detailId.value = res.data.id
} }
} else { } else {
detailId.value = ''
setFieldsValue({ permissionIdentity: unref(2) }) setFieldsValue({ permissionIdentity: unref(2) })
} }
setModalProps({ loading: false }) setModalProps({ loading: false })
}) })
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑')) const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'))
//
const feeField = ref()
async function handleSave(exit) { async function handleSave(exit) {
try { try {
const values = await validate() const values = await validate()
const feeList = feeField.value.validate()
values['detail'] = feeList
loading.value = true loading.value = true
setModalProps({ confirmLoading: true, loading: true }) setModalProps({ confirmLoading: true, loading: true })
const res: API.DataResult = await editFeeCurrency(values) const res: API.DataResult = await EditFeeTemplate(values)
loading.value = false loading.value = false
if (res.succeeded) { if (res.succeeded) {
createMessage.success(res.message) createMessage.success(res.message)

@ -9,15 +9,22 @@
<h2>费用字段</h2> <h2>费用字段</h2>
<div> <div>
<a-button type="primary" @click="addRow"></a-button> <a-button type="primary" @click="addRow"></a-button>
<a-button class="ml10" type="error" @click="deleteRow"></a-button> <a-popconfirm
title="确定删除当前选中的费用字段?"
ok-text="是"
cancel-text="否"
@confirm="deleteRow"
>
<a-button class="ml10" type="error">删除</a-button>
</a-popconfirm>
</div> </div>
</div> </div>
<BasicTable :rowSelection="{ type: 'checkbox' }" @register="registerTable"> <BasicTable :rowSelection="{ type: 'checkbox' }" :clickToRowSelect="false" @register="registerTable">
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<!-- 费用名称 --> <!-- 费用名称 -->
<a-select <a-select
v-if="column.key === 'name'" v-if="column.key === 'feeName'"
v-model:value="record.name" v-model:value="record.feeCode"
placeholder="请选择" placeholder="请选择"
@change="feeNameChange($event, record)" @change="feeNameChange($event, record)"
> >
@ -30,7 +37,7 @@
</a-select-option> </a-select-option>
</a-select> </a-select>
<!-- 费用英文名称 --> <!-- 费用英文名称 -->
<a-input v-else-if="column.key === 'enName'" v-model:value="record.enName" placeholder="请输入" /> <a-input v-else-if="column.key === 'feeEnName'" v-model:value="record.feeEnName" placeholder="请输入" />
<!-- 结算对象类型 --> <!-- 结算对象类型 -->
<a-select <a-select
v-else-if="column.key === 'customerType'" v-else-if="column.key === 'customerType'"
@ -94,15 +101,16 @@
<a-input-number <a-input-number
v-else-if="column.key === 'unitPrice'" v-else-if="column.key === 'unitPrice'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.unitPrice" v-model:value="record.unitPrice"
:min="0" :min="0"
:precision="2" :precision="2"
@blur="calcAmount(record, 'price')"
/> />
<!-- 汇率 --> <!-- 汇率 -->
<a-input-number <a-input-number
v-else-if="column.key === 'exchangeRate'" v-else-if="column.key === 'exchangeRate'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.exchangeRate" v-model:value="record.exchangeRate"
:min="0" :min="0"
:precision="2" :precision="2"
/> />
@ -110,23 +118,26 @@
<a-input-number <a-input-number
v-else-if="column.key === 'taxRate'" v-else-if="column.key === 'taxRate'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.taxRate" v-model:value="record.taxRate"
@blur="calcAmount(record, 'tax')"
:min="0" :min="0"
:max="100"
:precision="2" :precision="2"
/> />
<!-- 含税单价 --> <!-- 含税单价 -->
<a-input-number <a-input-number
v-else-if="column.key === 'taxUnitPrice'" v-else-if="column.key === 'taxUnitPrice'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.taxUnitPrice" v-model:value="record.taxUnitPrice"
:min="0" :min="0"
:precision="2" :precision="2"
@blur="calcAmount(record, 'taxPrice')"
/> />
<!-- 税额 --> <!-- 税额 -->
<a-input-number <a-input-number
v-else-if="column.key === 'tax'" v-else-if="column.key === 'tax'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.tax" v-model:value="record.tax"
:min="0" :min="0"
:precision="2" :precision="2"
/> />
@ -134,7 +145,7 @@
<a-input-number <a-input-number
v-else-if="column.key === 'accTaxRate'" v-else-if="column.key === 'accTaxRate'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.accTaxRate" v-model:value="record.accTaxRate"
:min="0" :min="0"
:precision="2" :precision="2"
/> />
@ -153,15 +164,15 @@
<a-input-number <a-input-number
v-else-if="column.key === 'orderNo'" v-else-if="column.key === 'orderNo'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.orderNo" v-model:value="record.orderNo"
:min="0" :min="0"
:precision="0" :precision="0"
/> />
<!-- 备注 --> <!-- 备注 -->
<a-input-number <a-input
v-else-if="column.key === 'note'" v-else-if="column.key === 'note'"
placeholder="请输入" placeholder="请输入"
v-model:value="column.note" v-model:value="record.note"
/> />
<!-- 费用分组 --> <!-- 费用分组 -->
<a-select <a-select
@ -182,26 +193,62 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue' import { ref, onMounted, defineProps, watch } from 'vue'
// //
import { GetFeeCodeSelectList, GetClientListByCode, GetFeeCurrencySelectList } from '/@/api/common' import { GetFeeCodeSelectList, GetClientListByCode, GetFeeCurrencySelectList } from '/@/api/common'
import { GetFeeTemplateDetailList, BatchDelFeeTemplateDetail } from '../api'
// //
import { getDictOption } from '/@/utils/dictUtil' import { getDictOption } from '/@/utils/dictUtil'
import { BasicTable, useTable, TableAction } from '/@/components/Table' import { BasicTable, useTable } from '/@/components/Table'
const [registerTable, { reload, setTableData, getDataSource, insertTableDataRecord, getSelectRowKeys, deleteTableDataRecord, getPaginationRef, getSelectRows }] = useTable({ import { useMessage } from '/@/hooks/web/useMessage'
api: async () => { const { createMessage, notification } = useMessage()
return new Promise((resolve) => { const props = defineProps({
resolve({ data: [{ name: '测试', enName: '' }] }) id: {
type: String
}
})
const [registerTable, { reload, setShowPagination, getDataSource, insertTableDataRecord, deleteTableDataRecord, getPaginationRef, getSelectRows }] = useTable({
api: async (p) => {
setShowPagination(false)
if (props.id) {
const res: API.DataResult = await GetFeeTemplateDetailList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
} else {
return new Promise((resolve) => {
resolve({ data: [] })
})
}
},
immediate: false,
beforeFetch: () => {
var currentPageInfo: any = getPaginationRef()
const postParam: API.PageRequest = {
queryCondition: '',
pageCondition: {
pageIndex: currentPageInfo.current,
pageSize: 100,
sortConditions: [],
}
}
let condition: API.ConditionItem[] = []
condition.push({
FieldName: 'TemplateId',
FieldValue: props.id,
ConditionalType: 1,
}) })
postParam.queryCondition = JSON.stringify(condition)
return postParam
}, },
columns: [ columns: [
{ {
title: '费用名称', title: '费用名称',
dataIndex: 'name', dataIndex: 'feeName',
width: 120 width: 120
}, { }, {
title: '费用英文名称', title: '费用英文名称',
dataIndex: 'enName', dataIndex: 'feeEnName',
width: 120 width: 120
}, { }, {
title: '结算对象类型', title: '结算对象类型',
@ -232,7 +279,7 @@
dataIndex: 'exchangeRate', dataIndex: 'exchangeRate',
width: 120 width: 120
}, { }, {
title: '税率', title: '税率(%)',
dataIndex: 'taxRate', dataIndex: 'taxRate',
width: 120 width: 120
}, { }, {
@ -293,6 +340,11 @@
// //
init() init()
}) })
watch(() => props.id,
() => {
reload()
}
)
// //
const init = async () => { const init = async () => {
const list = await GetFeeCodeSelectList() const list = await GetFeeCodeSelectList()
@ -308,7 +360,7 @@
const res = feeNameDict.value.filter(item => { const res = feeNameDict.value.filter(item => {
return item.code == e return item.code == e
})[0] })[0]
record.enName = res.enName || '' record.feeEnName = res.enName || ''
} }
// //
const companyDict = ref([]) const companyDict = ref([])
@ -326,14 +378,65 @@
// //
const addRow = () => { const addRow = () => {
insertTableDataRecord({ insertTableDataRecord({
key: new Date().getTime() key: new Date().getTime(),
feeFrt: '',
unit: '',
feeCode: '',
feeName: '',
currency: '',
feeGroup: '',
feeEnName: '',
customerName: '',
customerType: ''
}) })
} }
// //
const deleteRow = () => { const deleteRow = () => {
const keys = getSelectRowKeys() const rows = getSelectRows()
if (rows.length === 0) {
notification.error({ message: '请选择要删除的费用字段', duration: 3 })
return false
}
//
let apiId = []
//
let keys = []
rows.forEach(item => {
if (item.id) {
apiId.push(item.id)
} else {
keys.push(item.key)
}
})
// id
deleteTableDataRecord(keys) deleteTableDataRecord(keys)
// id
BatchDelFeeTemplateDetail({ ids: apiId, id: '' }).then(res => {
if (res.succeeded) {
createMessage.success(res.message)
reload()
} else {
createMessage.error(res.message)
}
})
} }
//
const calcAmount = (row, key) => {
if (key === 'tax' || key === 'taxPrice') {
// ( = ÷ (1 + ))
row.unitPrice = (row.taxUnitPrice / (Number(row.taxRate / 100 ) + 1))
} else {
// ( = *(1 + ))
row.taxUnitPrice = row.unitPrice || 0 * (1 + Number(row.taxRate || 0 / 100))
}
}
const validate = () => {
return getDataSource()
}
//
defineExpose({
validate
})
</script> </script>
<style lang="scss"> <style lang="scss">

@ -24,17 +24,27 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from 'vue' import { onMounted } from 'vue'
import { BasicTable, useTable, TableAction } from '/@/components/Table' import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getFeeCurrencyList } from './api' import { GetFeeTemplateList } from './api'
import { useModal } from '/@/components/Modal' import { useModal } from '/@/components/Modal'
import Modal from './components/Modal.vue' import Modal from './components/Modal.vue'
import { columns, searchFormSchema } from './columns' import { columns, searchFormSchema } from './columns'
//
import { getDictOption } from '/@/utils/dictUtil'
const [registerModal, { openModal }] = useModal() const [registerModal, { openModal }] = useModal()
const [registerTable, { reload, getForm, getPaginationRef }] = useTable({ const [registerTable, { reload, getForm, getPaginationRef }] = useTable({
title: '费用模版', title: '费用模版',
// api: getSysDictTypeList, // api: getSysDictTypeList,
api: async (p) => { api: async (p) => {
const res: API.DataResult = await getFeeCurrencyList(p) const res: API.DataResult = await GetFeeTemplateList(p)
// console.log(items); //
const dicts = await getDictOption('business_type')
res?.data.forEach(row => {
dicts.forEach(item => {
if (item.value == row.opType) {
row.opTypeName = item.label
}
})
})
return new Promise((resolve) => { return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count }) resolve({ data: [...res.data], total: res.count })
}) })

Loading…
Cancel
Save