1.1.12 添加合同回款页面
parent
681b574beb
commit
0e86a7758c
@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form v-show="showSearch" :model="queryParams" :inline="true" label-width="90px">
|
||||
<el-form-item label="部门">
|
||||
<el-input v-model="queryParams.deptName" clearable placeholder="请输入部门" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单编号">
|
||||
<el-input v-model="queryParams.orderNo" clearable placeholder="请输入订单编号" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同编号">
|
||||
<el-input v-model="queryParams.contractNo" clearable placeholder="请输入合同编号" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同名称">
|
||||
<el-input v-model="queryParams.contractName" clearable placeholder="请输入合同名称" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单名称">
|
||||
<el-input v-model="queryParams.orderName" clearable placeholder="请输入订单名称" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar v-model:showSearch="showSearch" :columns="columns" @queryTable="getList" />
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
border
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
:cell-style="{ textAlign: 'center' }"
|
||||
>
|
||||
<el-table-column v-if="columns[0].visible" label="订单编号" prop="orderNo" min-width="140" />
|
||||
<el-table-column v-if="columns[1].visible" label="订单名称" prop="orderName" min-width="180" show-overflow-tooltip />
|
||||
|
||||
<el-table-column v-if="columns[2].visible" label="合同编号" prop="contractNo" min-width="140" />
|
||||
<el-table-column v-if="columns[3].visible" label="合同名称" prop="contractName" min-width="180" show-overflow-tooltip />
|
||||
|
||||
<el-table-column v-if="columns[4].visible" label="业务方向" min-width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="business_direction" :value="scope.row.businessDirection" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="columns[5].visible" label="部门" prop="deptName" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column v-if="columns[6].visible" label="合同金额" prop="amount" min-width="120" />
|
||||
<el-table-column v-if="columns[7].visible" label="回款比例(%)" prop="paymentRate" min-width="100">
|
||||
<template #default="scope">
|
||||
{{ scope.row.paymentRate ?? 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openStageDialog(scope.row)">回款确认</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<el-dialog v-model="stageDialogVisible" title="合同回款阶段确认" width="1200px">
|
||||
<el-table v-loading="stageLoading" :data="stageList" border>
|
||||
<el-table-column label="合同订单阶段" prop="stageName" min-width="130" />
|
||||
<el-table-column label="回款阶段标识" prop="collectionStage" min-width="120" />
|
||||
<el-table-column label="预计回款比例(%)" prop="repaymentRate" width="130" />
|
||||
<el-table-column label="合同阶段比例(%)" prop="paymentPercentage" width="130" />
|
||||
<el-table-column label="合同阶段金额" prop="paymentAmount" width="130" />
|
||||
<el-table-column label="实际回款金额" prop="actualRepaymentAmount" width="130" />
|
||||
<el-table-column label="确认状态" width="110">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="collection_confirm_status" :value="scope.row.collectionConfirmStatus || '0'" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="确认人" prop="collectionConfirmUserId" width="100" />
|
||||
<el-table-column label="确认时间" width="160">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.collectionConfirmTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="确认备注" prop="collectionConfirmRemark" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openConfirmDialog(scope.row)">确认</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="confirmDialogVisible" title="阶段回款确认" width="500px">
|
||||
<el-form :model="confirmForm" label-width="120px">
|
||||
<el-form-item label="实际回款日期" required>
|
||||
<el-date-picker v-model="confirmForm.receivableDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际回款金额" required>
|
||||
<el-input-number v-model="confirmForm.actualRepaymentAmount" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认状态">
|
||||
<el-select v-model="confirmForm.collectionConfirmStatus" clearable style="width: 100%">
|
||||
<el-option v-for="item in collection_confirm_status" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认备注">
|
||||
<el-input v-model="confirmForm.collectionConfirmRemark" type="textarea" :rows="3" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="confirmDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="confirmLoading" @click="submitConfirm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ContractCollectionPage">
|
||||
import { getCurrentInstance, reactive, ref, toRefs } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {
|
||||
confirmCollectionStage,
|
||||
contractCollectionPage,
|
||||
contractCollectionStageDetail
|
||||
} from '@/api/oa/erp/erpProjectPlan';
|
||||
import { ContractCollectionPageVO, ContractCollectionStageDetailVO } from '@/api/oa/erp/erpProjectPlan/types';
|
||||
import { ErpProjectPlanStageForm } from '@/api/oa/erp/erpProjectPlanStage/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { collection_confirm_status, business_direction } = toRefs(
|
||||
proxy?.useDict('collection_confirm_status', 'business_direction')
|
||||
);
|
||||
|
||||
const loading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
const total = ref(0);
|
||||
const list = ref<ContractCollectionPageVO[]>([]);
|
||||
const columns = ref([
|
||||
{ key: 0, label: '订单编号', visible: true },
|
||||
{ key: 1, label: '订单名称', visible: true },
|
||||
{ key: 2, label: '合同编号', visible: true },
|
||||
{ key: 3, label: '合同名称', visible: true },
|
||||
{ key: 4, label: '业务方向', visible: true },
|
||||
{ key: 5, label: '部门', visible: true },
|
||||
{ key: 6, label: '金额', visible: true },
|
||||
{ key: 7, label: '回款比例(%)', visible: true }
|
||||
]);
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
deptName: '',
|
||||
orderNo: '',
|
||||
contractNo: '',
|
||||
contractName: '',
|
||||
orderName: ''
|
||||
});
|
||||
|
||||
const stageDialogVisible = ref(false);
|
||||
const stageLoading = ref(false);
|
||||
const stageList = ref<ContractCollectionStageDetailVO[]>([]);
|
||||
|
||||
const confirmDialogVisible = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
const confirmForm = reactive<ErpProjectPlanStageForm>({
|
||||
planStageId: undefined,
|
||||
receivableDate: '',
|
||||
actualRepaymentAmount: 0,
|
||||
collectionConfirmStatus: '',
|
||||
collectionConfirmRemark: ''
|
||||
});
|
||||
const currentPlanId = ref<string | number>();
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await contractCollectionPage(queryParams);
|
||||
list.value = res.rows || [];
|
||||
total.value = res.total || 0;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.deptName = '';
|
||||
queryParams.orderNo = '';
|
||||
queryParams.contractNo = '';
|
||||
queryParams.contractName = '';
|
||||
queryParams.orderName = '';
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const openStageDialog = async (row: ContractCollectionPageVO) => {
|
||||
if (!row.projectPlanId) {
|
||||
ElMessage.warning('该记录未关联项目计划,无法进行阶段回款确认');
|
||||
return;
|
||||
}
|
||||
currentPlanId.value = row.projectPlanId;
|
||||
stageDialogVisible.value = true;
|
||||
stageLoading.value = true;
|
||||
const res = await contractCollectionStageDetail(row.projectPlanId);
|
||||
stageList.value = res.data || [];
|
||||
stageLoading.value = false;
|
||||
};
|
||||
|
||||
const openConfirmDialog = (row: ContractCollectionStageDetailVO) => {
|
||||
confirmForm.planStageId = row.planStageId;
|
||||
confirmForm.receivableDate = '';
|
||||
confirmForm.actualRepaymentAmount = row.actualRepaymentAmount || 0;
|
||||
confirmForm.collectionConfirmStatus = row.collectionConfirmStatus || '';
|
||||
confirmForm.collectionConfirmRemark = row.collectionConfirmRemark || '';
|
||||
confirmDialogVisible.value = true;
|
||||
};
|
||||
|
||||
const submitConfirm = async () => {
|
||||
if (!confirmForm.planStageId) {
|
||||
ElMessage.warning('缺少阶段ID');
|
||||
return;
|
||||
}
|
||||
if (!confirmForm.receivableDate) {
|
||||
ElMessage.warning('请选择实际回款日期');
|
||||
return;
|
||||
}
|
||||
confirmLoading.value = true;
|
||||
await confirmCollectionStage(confirmForm);
|
||||
confirmLoading.value = false;
|
||||
confirmDialogVisible.value = false;
|
||||
ElMessage.success('确认成功');
|
||||
if (currentPlanId.value) {
|
||||
const res = await contractCollectionStageDetail(currentPlanId.value);
|
||||
stageList.value = res.data || [];
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (val?: string) => {
|
||||
if (!val) return '';
|
||||
return String(val).replace('T', ' ').slice(0, 19);
|
||||
};
|
||||
|
||||
getList();
|
||||
</script>
|
||||
Loading…
Reference in New Issue