课程名称: SpringBoot+Vue3 项目实战,打造企业级在线办公系统
课程章节: 第9章 报销管理
主讲老师: 神思者
课程内容
在Emos当中,员工可以在管理页面上进行报销申请,然后管理员审批通过以后,能够生成pdf的费用报销单文件。详细可以查看思维导图:
费用报销的具体时序图参考如下:
同样也去请求了工作流项目,在工作流项目上发起申请。然后申请工单,审批通过以后,生成PDF文件。
课程收获
使用异步线程开启工作流审批
创建报销申请,既要向tb_reim
表保存数据,还要创建工作流实例,所以我们先把异步线程任务类创建出来,调用工作流项目的Web方法。
URI路径:/workflow/startReimProcess
序号 | 参数 | 类型 | 含义 |
---|---|---|---|
1 | url | String | 接收审批结果的URL地址 |
2 | creatorId | String | 申请人userId |
3 | creatorName | String | 申请人姓名 |
4 | code | String | 慕课网授权字符串 |
5 | tcode | String | 课程授权字符串 |
6 | title | String | 报销申请标题 |
7 | managerId | int | 部门经理的userId |
8 | gmId | int | 总经理的userId |
在com.example.emos.api.task
包中创建ReimWorkflowTask.java
类,代码如下:
@Component
@Slf4j
public class ReimWorkflowTask {
@Value("${emos.code}")
private String code;
@Value("${emos.tcode}")
private String tcode;
@Value("${workflow.url}")
private String workflow;
@Value("${emos.recieveNotify}")
private String recieveNotify;
@Autowired
private TbUserDao userDao;
@Autowired
private TbReimDao reimDao;
@Async("AsyncTaskExecutor")
public void startReimWorkflow(int id, int creatorId) {
HashMap info = userDao.searchUserInfo(creatorId);
JSONObject json = new JSONObject();
json.set("url", recieveNotify);
json.set("creatorId", creatorId);
json.set("creatorName", info.get("name").toString());
json.set("code", code);
json.set("tcode", tcode);
json.set("title", info.get("dept").toString() + info.get("name").toString() + "的报销");
Integer managerId = userDao.searchDeptManagerId(creatorId);
json.set("managerId", managerId);
Integer gmId = userDao.searchGmId();
json.set("gmId", gmId);
String url = workflow + "/workflow/startReimProcess";
HttpResponse resp = HttpRequest.post(url).header("Content-Type", "application/json")
.body(json.toString()).execute();
if (resp.getStatus() == 200) {
json = JSONUtil.parseObj(resp.body());
String instanceId = json.getStr("instanceId");
HashMap param = new HashMap();
param.put("id", id);
param.put("instanceId", instanceId);
int rows = reimDao.updateReimInstanceId(param);
if (rows != 1) {
throw new EmosException("保存报销申请工作流实例ID失败");
}
} else {
log.error(resp.body());
}
}
}
使用异步线程开启工作流审批
报销离不开发票,所以财务和领导在审批报销的时候要核对员工的报销票据。因此员工先要在报销管理页面下载PDF报销单,打印出来之后,贴好报销的发票。然后找财务和领导审核签字。
在报销单的右上角有二维码,内容是该报销申请的工作流实例instance_id。将来我们想要查询某个报销申请的时候,用扫码枪扫描这个二维码,就能查询到报销记录。
此处后端只返回了页面上所需要展示的字段数据,具体渲染实则放在前端实现。
具体代码实现如下:
报销单弹窗是reim_pdf.vue
页面,因为要生成PDF文件,所以页面DIV控件设置了id属性,而且属性值必须为pdfDom才行。
<el-dialog width="800px" :close-on-click-modal="false" v-model="visible" :show-close="false" center>
<div id="pdfDom">
<img :src="qrCodeBase64" class="qrCode" />
<h2 class="title">费 用 报 销 单</h2>
<div class="top-info-container">
<span class="info">报销部门:{{ dept }}</span>
<span class="info">报销人:{{ name }}</span>
<span class="info">报销日期:{{ date }}</span>
</div>
<div class="reim-table-container">
<table class="reim-table">
<tr align="center">
<th width="30%">报销项目</th>
<th width="34%">备注</th>
<th width="20%">类别</th>
<th width="16%">金额</th>
</tr>
<tr align="center" v-for="one in content">
<td align="left">{{ one.title }}</td>
<td align="left">{{ one.desc }}</td>
<td>{{ one.type }}</td>
<td align="left">{{ one.money != '' ? one.money + '元' : '' }}</td>
</tr>
<tr>
<th align="center">报销合计</th>
<td colspan="3">{{ amount }}元</td>
</tr>
<tr>
<th align="center">人民币大写</th>
<td colspan="3">{{ smalltoBIG(amount) }}</td>
</tr>
<tr>
<td colspan="5">
<div class="info-container">
<span class="info">借款金额:{{ anleihen }}元</span>
<span class="info">应退金额:{{ money_1 }}元</span>
<span class="info">应补金额:{{ money_2 }}元</span>
</div>
</td>
</tr>
</table>
</div>
<div class="bottom-info-container"></div>
<div class="bottom-info-container">
<span class="sig">会计主管:</span>
<span class="sig">复核:</span>
<span class="sig">出纳:</span>
<span class="sig">报销人:</span>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="getPdf()" size="medium">下载报销单</el-button>
<el-button size="medium" @click="cancel()">关闭窗口</el-button>
</span>
</template>
</el-dialog>
写弹窗页面的init()
函数,发起Ajax请求查询数据,然后把数据显示到报销单之中。
init: function(id) {
let that = this;
that.visible = true;
that.dept = null;
that.name = null;
that.date = null;
that.amount = null;
that.balance = null;
that.anleihen = null;
that.money_1 = 0;
that.money_2 = 0;
that.content = [];
that.$http('reim/searchReimById', 'POST', { id: id }, true, function(resp) {
that.dept = resp.dept;
that.name = resp.name;
that.date = resp.date;
that.amount = resp.amount;
that.balance = resp.balance;
that.anleihen = resp.anleihen;
if (that.anleihen > that.amount) {
that.money_1 = that.anleihen - that.amount;
} else if (that.anleihen < that.amount) {
that.money_2 = that.amount - that.anleihen;
}
let content = JSON.parse(resp.content);
let temp = 5 - content.length;
for (let i = 0; i < temp; i++) {
content.push({ title: '', desc: '', type: '', money: '' });
}
that.content = content;
that.qrCodeBase64 = resp.qrCodeBase64;
});
},
下载报销单
在main.js
文件中封装了生成PDF文件的函数,所以我们调用getPdf()
函数即可。
<span class="dialog-footer">
<el-button type="primary" @click="getPdf()" size="medium">下载报销单</el-button>
<el-button size="medium" @click="cancel()">关闭窗口</el-button>
</span>
课程截图
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦