feat(finance): 新增财务票据审批功能
- 在配置文件中增加财务票据相关流程定义 - 实现票据退款审批流程的开启与处理逻辑 - 新增付款退款审批页面及详情组件 - 提供付款退款审批接口及业务方法 - 支持在审批流中动态设置流程变量并启动指定流程 - 优化审批节点信息填充方法以支持多流程场景 - 修复部分SQL查询条件限制提高灵活性 - 更新前端页面去除冗余字段展示提升用户体验dev_1.0.0
parent
995f7f8b03
commit
56d79e96b6
|
|
@ -0,0 +1,34 @@
|
|||
import request from '@/utils/request'
|
||||
import {tansParams} from "@/utils/ruoyi";
|
||||
|
||||
// 查询付款退款待审批列表
|
||||
export function listPaymentRefundApprove(query) {
|
||||
return request({
|
||||
url: '/finance/payment/approve/list',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
data: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询付款退款已审批列表
|
||||
export function listPaymentRefundApproved(query) {
|
||||
return request({
|
||||
url: '/finance/payment/approved/list',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询付款退款详情
|
||||
export function getPaymentRefund(id) {
|
||||
return request({
|
||||
url: '/finance/paymentRefund/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
@ -20,9 +20,9 @@
|
|||
<el-table-column label="序号" type="index" width="50" align="center" />
|
||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" />
|
||||
<el-table-column label="汇智负责人" align="center" prop="hzUserName" />
|
||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -84,7 +84,8 @@ export default {
|
|||
pageSize: 10,
|
||||
paymentNo: null,
|
||||
manufacturer: null,
|
||||
projectName: null
|
||||
projectName: null,
|
||||
processKey: 'finance_payment',
|
||||
},
|
||||
detailDialogVisible: false,
|
||||
detailLoading: false,
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@
|
|||
<el-table-column label="序号" type="index" width="50" align="center" />
|
||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" />
|
||||
<el-table-column label="汇智负责人" align="center" prop="hzUserName" />
|
||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
||||
<template slot-scope="scope">
|
||||
|
|
@ -111,7 +111,8 @@ export default {
|
|||
pageSize: 10,
|
||||
paymentNo: null,
|
||||
manufacturer: null,
|
||||
projectName: null
|
||||
projectName: null,
|
||||
processKey: 'finance_payment',
|
||||
},
|
||||
detailDialogVisible: false,
|
||||
detailLoading: false,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
||||
<el-form-item label="付款编号" prop="paymentNo">
|
||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="制造商" prop="manufacturer">
|
||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="paymentList">
|
||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" />
|
||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
||||
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog title="付款单详情" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
||||
<ApproveLayout title="付款单详情">
|
||||
<payment-detail :data="form"></payment-detail>
|
||||
<template #footer>
|
||||
<span>付款编号: {{ form.paymentBillCode }}</span>
|
||||
</template>
|
||||
</ApproveLayout>
|
||||
|
||||
<el-divider content-position="left">流转意见</el-divider>
|
||||
<div class="process-container">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
||||
<el-card>
|
||||
<h4>{{ log.approveOpinion }}</h4>
|
||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
||||
<p><b>审批状态:</b> <el-tag size="small">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPaymentApproved, getPayment } from "@/api/finance/payment";
|
||||
import { listCompletedFlows } from "@/api/flow";
|
||||
import PaymentDetail from "../components/PaymentRefundDetail.vue"; // Relative path adjustment
|
||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
||||
|
||||
export default {
|
||||
name: "PaymentApproved",
|
||||
components: { PaymentDetail, ApproveLayout },
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
showSearch: true,
|
||||
total: 0,
|
||||
paymentList: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
paymentNo: null,
|
||||
manufacturer: null,
|
||||
projectName: null,
|
||||
processKey: 'finance_refund',
|
||||
},
|
||||
detailDialogVisible: false,
|
||||
detailLoading: false,
|
||||
form: {},
|
||||
approveLogs: [],
|
||||
currentPaymentId: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listPaymentApproved(this.queryParams).then(response => {
|
||||
this.paymentList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
handleView(row) {
|
||||
this.form = {};
|
||||
this.approveLogs = [];
|
||||
this.currentPaymentId = row.id;
|
||||
this.detailLoading = true;
|
||||
this.detailDialogVisible = true;
|
||||
|
||||
getPayment(this.currentPaymentId).then(response => {
|
||||
this.form = response.data;
|
||||
this.loadApproveHistory(this.form.paymentBillCode);
|
||||
this.detailLoading = false;
|
||||
}).catch(() => {
|
||||
this.detailLoading = false;
|
||||
});
|
||||
},
|
||||
loadApproveHistory(businessKey) {
|
||||
if (businessKey) {
|
||||
listCompletedFlows({ businessKey: businessKey }).then(response => {
|
||||
this.approveLogs = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
||||
return map[status] || '提交审批';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.process-container {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<div class="payment-refund-detail">
|
||||
<el-descriptions title="付款退款单信息" :column="3" border>
|
||||
<el-descriptions-item label="采购付款单编号">{{ data.paymentBillCode }}</el-descriptions-item>
|
||||
<el-descriptions-item label="制造商名称">{{ data.vendorName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="付款单类型">
|
||||
<dict-tag :options="dict.type.payment_bill_type" :value="data.paymentBillType"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="含税总价">{{ data.totalPriceWithTax }}</el-descriptions-item>
|
||||
<el-descriptions-item label="未税总价">{{ data.totalPriceWithoutTax }}</el-descriptions-item>
|
||||
<el-descriptions-item label="税额">{{ data.taxAmount }}</el-descriptions-item>
|
||||
<el-descriptions-item label="付款方式">
|
||||
<dict-tag :options="dict.type.payment_method" :value="data.paymentMethod"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="银行账号">{{ data.payBankNumber }}</el-descriptions-item>
|
||||
<el-descriptions-item label="账户名称">{{ data.payName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="银行开户行">{{ data.payBankOpenAddress }}</el-descriptions-item>
|
||||
<el-descriptions-item label="银行行号">{{ data.bankNumber }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="3">{{ data.remark }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div class="section" style="margin-top: 20px;" v-show="data.payableDetails && data.payableDetails.length>0">
|
||||
<div class="el-descriptions__title">退款明细列表</div>
|
||||
<el-table :data="data.payableDetails" border style="width: 100%; margin-top: 10px;">
|
||||
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
|
||||
<el-table-column prop="payableBillCode" label="采购应付单编号" align="center"></el-table-column>
|
||||
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
|
||||
<!-- Note: Product Type is requested but not present in reference DetailDrawer.vue. Omitting for safety or need to ask. -->
|
||||
<el-table-column prop="totalPriceWithTax" label="含税总价" align="center"></el-table-column>
|
||||
<el-table-column prop="paymentAmount" label="本次付款金额" align="center"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PaymentRefundDetail",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
dicts: ['payment_bill_type', 'payment_method']
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.payment-refund-detail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
||||
<el-form-item label="付款编号" prop="paymentNo">
|
||||
<el-input v-model="queryParams.paymentNo" placeholder="请输入付款编号" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="制造商" prop="manufacturer">
|
||||
<el-input v-model="queryParams.manufacturer" placeholder="请输入制造商" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="mini"
|
||||
@click="toApproved()"
|
||||
>审批历史</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="paymentList">
|
||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
||||
<el-table-column label="付款编号" align="center" prop="paymentBillCode" />
|
||||
<el-table-column label="制造商" align="center" prop="vendorName" />
|
||||
<!-- <el-table-column label="项目名称" align="center" prop="projectName" />-->
|
||||
<el-table-column label="金额" align="center" prop="totalPriceWithTax" />
|
||||
<!-- <el-table-column label="汇智负责人" align="center" prop="hzUserName" />-->
|
||||
<el-table-column label="审批节点" align="center" prop="approveNode" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(scope.row)">审批</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
||||
|
||||
<!-- 审批详情主对话框 -->
|
||||
<el-dialog title="付款单审批" :visible.sync="detailDialogVisible" width="80%" append-to-body>
|
||||
<div v-loading="detailLoading" style="max-height: 70vh; overflow-y: auto; padding: 20px;">
|
||||
<ApproveLayout title="付款单详情">
|
||||
<payment-detail :data="form"></payment-detail>
|
||||
<template #footer>
|
||||
<span>付款编号: {{ form.paymentBillCode }}</span>
|
||||
</template>
|
||||
</ApproveLayout>
|
||||
|
||||
<el-divider content-position="left">流转意见</el-divider>
|
||||
<div class="process-container">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(log, index) in approveLogs" :key="index" :timestamp="log.approveTime" placement="top">
|
||||
<el-card>
|
||||
<h4>{{ log.approveOpinion }}</h4>
|
||||
<p><b>操作人:</b> {{ log.approveUserName }} </p>
|
||||
<p><b>审批状态:</b> <el-tag size="small">{{ getStatusText(log.approveStatus) }}</el-tag></p>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
<div v-if="!approveLogs || approveLogs.length === 0">暂无流转过程数据。</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="openOpinionDialog('approve')">同意</el-button>
|
||||
<el-button type="danger" @click="openOpinionDialog('reject')">驳回</el-button>
|
||||
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 审批意见对话框 -->
|
||||
<el-dialog :title="confirmDialogTitle" :visible.sync="opinionDialogVisible" width="30%" append-to-body>
|
||||
<el-form ref="opinionForm" :model="opinionForm" :rules="opinionRules" label-width="100px">
|
||||
<el-form-item label="审批意见" prop="approveOpinion">
|
||||
<el-input v-model="opinionForm.approveOpinion" type="textarea" :rows="4" placeholder="请输入审批意见"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="opinionDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="showConfirmDialog()">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPaymentApprove, getPayment } from "@/api/finance/payment";
|
||||
import { approveTask, listCompletedFlows } from "@/api/flow";
|
||||
import PaymentDetail from "./components/PaymentRefundDetail.vue";
|
||||
import ApproveLayout from "@/views/approve/ApproveLayout";
|
||||
|
||||
export default {
|
||||
name: "PaymentApprove",
|
||||
components: { PaymentDetail, ApproveLayout },
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
showSearch: true,
|
||||
total: 0,
|
||||
paymentList: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
paymentNo: null,
|
||||
manufacturer: null,
|
||||
projectName: null,
|
||||
processKey: 'finance_refund',
|
||||
},
|
||||
detailDialogVisible: false,
|
||||
detailLoading: false,
|
||||
form: {},
|
||||
approveLogs: [],
|
||||
opinionDialogVisible: false,
|
||||
confirmDialogTitle: '',
|
||||
currentApproveType: '',
|
||||
opinionForm: {
|
||||
approveOpinion: ''
|
||||
},
|
||||
opinionRules: {
|
||||
approveOpinion: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
|
||||
},
|
||||
processKey: 'finance_refund',
|
||||
taskId: null,
|
||||
currentPaymentId: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listPaymentApprove(this.queryParams).then(response => {
|
||||
this.paymentList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
toApproved() {
|
||||
this.$router.push( '/approve/paymentLog' )
|
||||
},
|
||||
handleApprove(row) {
|
||||
this.resetDetailForm();
|
||||
this.currentPaymentId = row.id;
|
||||
this.taskId = row.taskId;
|
||||
this.detailLoading = true;
|
||||
this.detailDialogVisible = true;
|
||||
|
||||
getPayment(this.currentPaymentId).then(response => {
|
||||
this.form = response.data;
|
||||
this.loadApproveHistory(this.form.paymentBillCode);
|
||||
this.detailLoading = false;
|
||||
}).catch(() => {
|
||||
this.detailLoading = false;
|
||||
});
|
||||
},
|
||||
resetDetailForm() {
|
||||
this.form = {};
|
||||
this.approveLogs = [];
|
||||
this.opinionForm.approveOpinion = '';
|
||||
},
|
||||
loadApproveHistory(businessKey) {
|
||||
if (businessKey) {
|
||||
// Assuming processKeyList might be generic or specific, using generic fetch for now
|
||||
// Usually need to know the specific process key. For payment, it might be 'payment_approval' etc.
|
||||
// However, listCompletedFlows logic in reference used specific keys.
|
||||
// If I don't know the key, maybe I can omit it or guess.
|
||||
// The reference used `processKeyList: ['purchase_order_online']`.
|
||||
// I will use a generic one or try to find it.
|
||||
// If row.processKey is available I can use that.
|
||||
let keys = [];
|
||||
console.log(this.processKey)
|
||||
if(this.processKey) keys.push(this.processKey);
|
||||
|
||||
listCompletedFlows({ businessKey: businessKey, processKeyList: keys }).then(response => {
|
||||
this.approveLogs = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
openOpinionDialog(type) {
|
||||
this.currentApproveType = type;
|
||||
this.confirmDialogTitle = type === 'approve' ? '同意审批' : '驳回审批';
|
||||
this.opinionDialogVisible = true;
|
||||
this.opinionForm.approveOpinion = '';
|
||||
this.$nextTick(() => {
|
||||
if(this.$refs.opinionForm) this.$refs.opinionForm.clearValidate();
|
||||
});
|
||||
},
|
||||
showConfirmDialog() {
|
||||
this.$refs.opinionForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.opinionDialogVisible = false;
|
||||
this.submitApproval();
|
||||
}
|
||||
});
|
||||
},
|
||||
submitApproval() {
|
||||
const approveBtn = this.currentApproveType === 'approve' ? 1 : 0;
|
||||
const params = {
|
||||
businessKey: this.form.paymentBillCode,
|
||||
processKey: this.processKey,
|
||||
taskId: this.taskId,
|
||||
variables: {
|
||||
comment: this.opinionForm.approveOpinion,
|
||||
approveBtn: approveBtn
|
||||
}
|
||||
};
|
||||
|
||||
approveTask(params).then(() => {
|
||||
this.$modal.msgSuccess(this.confirmDialogTitle + "成功");
|
||||
this.detailDialogVisible = false;
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
getStatusText(status) {
|
||||
if (!status) {
|
||||
return '提交审批'
|
||||
}
|
||||
// Map status codes to text
|
||||
const map = { '1': '提交审批', '2': '驳回', '3': '批准' };
|
||||
return map[status] || '提交审批';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.process-container {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -147,6 +147,7 @@ process:
|
|||
purchaseOrderApprove: purchase_order_online
|
||||
financePayment: finance_payment
|
||||
financeRefund: finance_refund
|
||||
fiananceTicket: fianance_ticket
|
||||
|
||||
#业务执行实例bean name ,可以按审批节点配置 业务审批回调方法处理业务逻辑. key 为流程节点主键ID value 要执行的业务方法名称,不配置则默认调用TodoCommonTemplate.todoApproveCallback
|
||||
instance:
|
||||
|
|
@ -160,6 +161,8 @@ process:
|
|||
beanName: omsPaymentBillServiceImpl
|
||||
financeRefund:
|
||||
beanName: omsPaymentBillServiceImpl
|
||||
fiananceTicket:
|
||||
beanName: omsTicketBillServiceImpl
|
||||
unis:
|
||||
inventory:
|
||||
allAuthRole: 103,101
|
||||
|
|
|
|||
|
|
@ -15,5 +15,7 @@ public class Definition {
|
|||
private String purchaseOrderApprove;
|
||||
private String financePayment;
|
||||
private String financeRefund;
|
||||
private String fiananceTicket;
|
||||
private String financeTicketRefound;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ public class Instance {
|
|||
private Map<String, Object> purchase_order_online;
|
||||
private Map<String, Object> finance_payment;
|
||||
private Map<String, Object> finance_refund;
|
||||
private Map<String, Object> fianance_ticket;
|
||||
private Map<String, Object> finance_ticket_refound;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package com.ruoyi.sip.controller;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.config.flow.ProcessConfig;
|
||||
import com.ruoyi.sip.domain.OmsFinAttachment;
|
||||
import com.ruoyi.sip.flowable.service.TodoService;
|
||||
import com.ruoyi.sip.service.IOmsFinAttachmentService;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -36,6 +40,10 @@ public class OmsPaymentBillController extends BaseController
|
|||
private IOmsPaymentBillService omsPaymentBillService;
|
||||
@Autowired
|
||||
private IOmsFinAttachmentService omsFinAttachmentService;
|
||||
@Autowired
|
||||
private TodoService todoService;
|
||||
@Autowired
|
||||
private ProcessConfig processConfig;
|
||||
|
||||
@RequiresPermissions("finance:payment:view")
|
||||
@GetMapping()
|
||||
|
|
@ -54,6 +62,10 @@ public class OmsPaymentBillController extends BaseController
|
|||
{
|
||||
startPage();
|
||||
List<OmsPaymentBill> list = omsPaymentBillService.selectOmsPaymentBillList(omsPaymentBill);
|
||||
clearPage();
|
||||
todoService.fillApproveNode(list,
|
||||
Arrays.asList(processConfig.getDefinition().getFinancePayment(), processConfig.getDefinition().getFinanceRefund())
|
||||
, OmsPaymentBill::getPaymentBillCode, (a, b) -> a.setApproveNode(b.get(a.getPaymentBillCode())));
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +76,10 @@ public class OmsPaymentBillController extends BaseController
|
|||
public TableDataInfo listApprove(OmsPaymentBill omsPaymentBill) {
|
||||
startPage();
|
||||
List<OmsPaymentBill> list = omsPaymentBillService.listApprove(omsPaymentBill);
|
||||
clearPage();
|
||||
todoService.fillApproveNode(list,
|
||||
Arrays.asList(processConfig.getDefinition().getFinancePayment(), processConfig.getDefinition().getFinanceRefund())
|
||||
, OmsPaymentBill::getPaymentBillCode, (a, b) -> a.setApproveNode(b.get(a.getPaymentBillCode())));
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +89,10 @@ public class OmsPaymentBillController extends BaseController
|
|||
public TableDataInfo listApproved(OmsPaymentBill omsPaymentBill) {
|
||||
startPage();
|
||||
List<OmsPaymentBill> list = omsPaymentBillService.listApproved(omsPaymentBill);
|
||||
clearPage();
|
||||
todoService.fillApproveNode(list,
|
||||
Arrays.asList(processConfig.getDefinition().getFinancePayment(), processConfig.getDefinition().getFinanceRefund())
|
||||
, OmsPaymentBill::getPaymentBillCode, (a, b) -> a.setApproveNode(b.get(a.getPaymentBillCode())));
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import org.flowable.engine.runtime.ProcessInstance;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 待办Service接口
|
||||
|
|
@ -137,6 +139,7 @@ public interface TodoService
|
|||
void fillOrderApproveNode(List<ProjectOrderInfo> list);
|
||||
|
||||
void fillPurchaseOrderApproveNode(List<OmsPurchaseOrder> list);
|
||||
<T> void fillApproveNode(List<T> list, List<String> processKeyList, Function<T, String> function, BiConsumer<T, Map<String, String>> consumer);
|
||||
|
||||
|
||||
AjaxResult statisticsTodo();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import javax.annotation.Resource;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -335,7 +337,7 @@ public class TodoServiceImpl implements TodoService {
|
|||
// String orderFlowKey = ProjectOrderInfo.ProcessTypeEnum.ONLINE.getCode().equals(projectOrderInfo.getProcessType()) ?
|
||||
// orderOnlineFlowKey : orderOfflineFlowKey;
|
||||
//启动流程
|
||||
ProcessInstance processInstance = startProcess(flowBusinessKey, variables, processConfig.getDefinition().getFinancePayment());
|
||||
ProcessInstance processInstance = startProcess(flowBusinessKey, variables,processKey);
|
||||
completed(null, null, flowBusinessKey);
|
||||
return processInstance;
|
||||
}
|
||||
|
|
@ -399,6 +401,23 @@ public class TodoServiceImpl implements TodoService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void fillApproveNode(List<T> list, List<String> processKeyList, Function<T, String> function, BiConsumer<T, Map<String, String>> consumer) {
|
||||
List<String> businessKeyList = list.stream().map(function).collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(businessKeyList)) {
|
||||
return;
|
||||
}
|
||||
List<Todo> todoList = todoMapper.listTodoByBusinessKeyAndProcessKey(businessKeyList, processKeyList);
|
||||
Map<String, String> approveUserNameMap = todoList.stream()
|
||||
.collect(Collectors.groupingBy(Todo::getBusinessKey,
|
||||
Collectors.mapping(Todo::getApproveUserName,
|
||||
Collectors.joining("、"))));
|
||||
|
||||
for (T orderInfo : list) {
|
||||
consumer.accept(orderInfo, approveUserNameMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult statisticsTodo() {
|
||||
Long userId = ShiroUtils.getUserId();
|
||||
|
|
|
|||
|
|
@ -61,4 +61,6 @@ public interface OmsTicketBillMapper
|
|||
|
||||
public int selectMaxCodeByPrefix(String codePrefix);
|
||||
|
||||
void updateOmsTicketBillByCode(OmsTicketBill omsTicketBill);
|
||||
|
||||
}
|
||||
|
|
@ -279,7 +279,7 @@ public class OmsPaymentBillServiceImpl implements IOmsPaymentBillService , TodoC
|
|||
} else {
|
||||
if (approveBtn.equals(0)) {
|
||||
handleRejectOrder(businessKey);
|
||||
}else{
|
||||
}else if (taskName.startsWith("财务")){
|
||||
handleCompanyLeaderApproval(businessKey);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.ruoyi.sip.service.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.config.flow.ProcessConfig;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.enums.ApproveStatusEnum;
|
||||
|
|
@ -15,9 +17,13 @@ import com.ruoyi.common.utils.StringUtils;
|
|||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.sip.domain.*;
|
||||
import com.ruoyi.sip.domain.dto.PaymentBillPayableDetailDTO;
|
||||
import com.ruoyi.sip.flowable.domain.Todo;
|
||||
import com.ruoyi.sip.flowable.service.TodoCommonTemplate;
|
||||
import com.ruoyi.sip.flowable.service.TodoService;
|
||||
import com.ruoyi.sip.service.IOmsFinAttachmentService;
|
||||
import com.ruoyi.sip.service.IOmsPayableBillService;
|
||||
import com.ruoyi.sip.service.IOmsPayableTicketDetailService;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.sip.mapper.OmsTicketBillMapper;
|
||||
|
|
@ -35,7 +41,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
||||
public class OmsTicketBillServiceImpl implements IOmsTicketBillService, TodoCommonTemplate
|
||||
{
|
||||
@Autowired
|
||||
private OmsTicketBillMapper omsTicketBillMapper;
|
||||
|
|
@ -45,7 +51,11 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
private IOmsFinAttachmentService omsFinAttachmentService;
|
||||
@Autowired
|
||||
private IOmsPayableBillService payableBillService;
|
||||
@Autowired
|
||||
private TodoService todoService;
|
||||
|
||||
@Autowired
|
||||
private ProcessConfig processConfig;
|
||||
/**
|
||||
* 查询采购收票单
|
||||
*
|
||||
|
|
@ -182,7 +192,11 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
omsTicketBill.setTicketPriceWithoutTax(bill.getTicketPriceWithoutTax());
|
||||
omsTicketBill.setTicketType(bill.getTicketType());
|
||||
updateOmsTicketBill(omsTicketBill);
|
||||
//todo 开启审批流程
|
||||
todoService.startProcessDeleteBefore(omsTicketBill.getTicketBillCode(), omsTicketBill.getTicketBillCode(),
|
||||
new HashMap<String, Object>() {{
|
||||
put("applyUserName", ShiroUtils.getSysUser().getUserName());
|
||||
put("applyUser", ShiroUtils.getUserId());
|
||||
}}, processConfig.getDefinition().getFiananceTicket());
|
||||
return AjaxResult.success(attachment);
|
||||
}
|
||||
|
||||
|
|
@ -231,11 +245,12 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
updateOmsTicketBill(originalBill);
|
||||
//4 创建付款明细
|
||||
payableTicketDetailService.applyRefund(originalBill.getTicketBillCode(),refundBill.getTicketBillCode());
|
||||
//5.todo 开始退款审批流程
|
||||
|
||||
|
||||
|
||||
|
||||
//5. 开始退款审批流程
|
||||
todoService.startProcessDeleteBefore(originalBill.getTicketBillCode(), originalBill.getTicketBillCode(),
|
||||
new HashMap<String, Object>() {{
|
||||
put("applyUserName", ShiroUtils.getSysUser().getUserName());
|
||||
put("applyUser", ShiroUtils.getUserId());
|
||||
}}, processConfig.getDefinition().getFinanceTicketRefound());
|
||||
|
||||
return AjaxResult.success("退款申请已提交,新的退款单号为:" + refundBill.getTicketBillCode());
|
||||
}
|
||||
|
|
@ -272,4 +287,61 @@ public class OmsTicketBillServiceImpl implements IOmsTicketBillService
|
|||
throw new RuntimeException("退回付款单操作失败:" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object todoDetail(String businessKey, String processKey, String todoId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object completedTodoDetail(String businessKey, String processKey, String todoId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean todoApproveCallback(Todo todo) {
|
||||
|
||||
if (CollUtil.isEmpty(todo.getVariables())) {
|
||||
return TodoCommonTemplate.super.todoApproveCallback(todo);
|
||||
}
|
||||
|
||||
Integer approveBtn = (Integer) todo.getVariables().get("approveBtn");
|
||||
if (approveBtn == null) {
|
||||
return TodoCommonTemplate.super.todoApproveCallback(todo);
|
||||
}
|
||||
String taskName = todo.getTaskName();
|
||||
String businessKey = todo.getBusinessKey();
|
||||
|
||||
if (approveBtn.equals(0)) {
|
||||
handleRejectOrder(businessKey);
|
||||
} else if (taskName.startsWith("财务")) {
|
||||
handleCompanyLeaderApproval(businessKey);
|
||||
}
|
||||
return TodoCommonTemplate.super.todoApproveCallback(todo);
|
||||
}
|
||||
private void handleRejectOrder(String businessKey) {
|
||||
OmsTicketBill omsTicketBill = new OmsTicketBill();
|
||||
omsTicketBill.setTicketBillCode(businessKey);
|
||||
omsTicketBill.setApproveStatus(ApproveStatusEnum.APPROVE_REJECT.getCode());
|
||||
omsTicketBillMapper.updateOmsTicketBillByCode(omsTicketBill);
|
||||
}
|
||||
private void handleCompanyLeaderApproval(String businessKey){
|
||||
OmsTicketBill omsTicketBill = new OmsTicketBill();
|
||||
omsTicketBill.setTicketBillCode(businessKey);
|
||||
omsTicketBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
|
||||
omsTicketBill.setApproveTime(DateUtils.getNowDate());
|
||||
omsTicketBillMapper.updateOmsTicketBillByCode(omsTicketBill);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean multiInstanceApproveCallback(String activityName, ProcessInstance processInstance) {
|
||||
return TodoCommonTemplate.super.multiInstanceApproveCallback(activityName, processInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillBusinessInfo(List<Todo> todoCompletedList) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +137,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<select id="selectOmsPaymentBillById" parameterType="Long" resultMap="OmsPaymentBillResult">
|
||||
<include refid="selectOmsPaymentBillVo"/>
|
||||
where pb.id = #{id}
|
||||
group by pb.id
|
||||
|
||||
</select>
|
||||
|
||||
<insert id="insertOmsPaymentBill" parameterType="OmsPaymentBill" useGeneratedKeys="true" keyProperty="id">
|
||||
|
|
@ -351,7 +351,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
left join oms_vendor_info t2 on pb.vendor_code = t2.vendor_code
|
||||
left join project_order_info t4 on pb.order_code = t4.order_code
|
||||
left join sys_user t5 on t5.user_id = t4.duty
|
||||
inner join ${tableName} t3 on (t3.process_key in ('finance_payment') and t3.approve_user=#{entity.approveUser} and t3.task_name!='商务' and t3.business_key=pb.payment_bill_code)
|
||||
inner join ${tableName} t3 on (t3.process_key in (#{entity.processKey}) and t3.approve_user=#{entity.approveUser} and t3.task_name!='商务' and t3.business_key=pb.payment_bill_code)
|
||||
<where>
|
||||
<if test="entity.paymentBillCode != null and entity.paymentBillCode != ''"> and pb.payment_bill_code like concat('%', #{entity.paymentBillCode}, '%')</if>
|
||||
<if test="entity.paymentBillType != null and entity.paymentBillType != ''"> and pb.payment_bill_type = #{entity.paymentBillType}</if>
|
||||
|
|
|
|||
|
|
@ -315,6 +315,79 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
<update id="updateOmsTicketBillByCode">
|
||||
update oms_ticket_bill
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
|
||||
<if test="ticketType != null and ticketType != ''">
|
||||
ticket_type = #{ticketType},
|
||||
</if>
|
||||
<if test="ticketBillType != null and ticketBillType != ''">
|
||||
ticket_bill_type = #{ticketBillType},
|
||||
</if>
|
||||
<if test="vendorTicketTime != null">
|
||||
vendor_ticket_time = #{vendorTicketTime},
|
||||
</if>
|
||||
<if test="ticketTime != null">
|
||||
ticket_time = #{ticketTime},
|
||||
</if>
|
||||
<if test="vendorCode != null and vendorCode != ''">
|
||||
vendor_code = #{vendorCode},
|
||||
</if>
|
||||
<if test="totalPriceWithTax != null">
|
||||
total_price_with_tax = #{totalPriceWithTax},
|
||||
</if>
|
||||
<if test="ticketPriceWithTax != null">
|
||||
ticket_price_with_tax = #{ticketPriceWithTax},
|
||||
</if>
|
||||
<if test="totalPriceWithoutTax != null">
|
||||
total_price_without_tax = #{totalPriceWithoutTax},
|
||||
</if>
|
||||
<if test="ticketPriceWithoutTax != null">
|
||||
ticket_price_without_tax = #{ticketPriceWithoutTax},
|
||||
</if>
|
||||
<if test="taxRate != null">
|
||||
tax_rate = #{taxRate},
|
||||
</if>
|
||||
<if test="createBy != null and createBy != ''">
|
||||
create_by = #{createBy},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime},
|
||||
</if>
|
||||
<if test="updateBy != null and updateBy != ''">
|
||||
update_by = #{updateBy},
|
||||
</if>
|
||||
<if test="updateTime != null">
|
||||
update_time = #{updateTime},
|
||||
</if>
|
||||
<if test="remark != null and remark != ''">
|
||||
remark = #{remark},
|
||||
</if>
|
||||
<if test="delFlag != null and delFlag != ''">
|
||||
del_flag = #{delFlag},
|
||||
</if>
|
||||
<if test="actualTicketTime != null">
|
||||
actual_ticket_time = #{actualTicketTime},
|
||||
</if>
|
||||
<if test="ticketStatus != null and ticketStatus != ''">
|
||||
ticket_status = #{ticketStatus},
|
||||
</if>
|
||||
<if test="approveStatus != null and approveStatus != ''">
|
||||
approve_status = #{approveStatus},
|
||||
</if>
|
||||
<if test="approveNode != null and approveNode != ''">
|
||||
approve_node = #{approveNode},
|
||||
</if>
|
||||
<if test="approveTime != null">
|
||||
approve_time = #{approveTime},
|
||||
</if>
|
||||
<if test="refundStatus != null and refundStatus != ''">
|
||||
refund_status = #{refundStatus},
|
||||
</if>
|
||||
</trim>
|
||||
where ticket_bill_code = #{ticketBillCode}
|
||||
</update>
|
||||
|
||||
<delete id="deleteOmsTicketBillById" parameterType="Long">
|
||||
delete from oms_ticket_bill where id = #{id}
|
||||
|
|
|
|||
Loading…
Reference in New Issue