OA表单打印,输入框回填

This commit is contained in:
wanggeng 2022-05-11 18:25:44 +08:00
parent a36568cb05
commit aadb902d22
13 changed files with 269 additions and 37 deletions

View File

@ -59,4 +59,14 @@ public class OaFormReportRouteController extends DefaultBaseController {
oaFormReportRouteService.show(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse);
}
@GetMapping("print/code/{formCode}/version/{formVersion}/uid/{uid}")
public void print(@PathVariable("formCode") String formCode,
@PathVariable("formVersion") Integer formVersion,
@PathVariable("uid") String uid,
HttpSession httpSession,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
oaFormReportRouteService.print(formCode, formVersion, uid, httpSession, httpServletRequest, httpServletResponse);
}
}

View File

@ -0,0 +1,31 @@
package ink.wgink.module.activiti.enums.oa.field;
/**
* @ClassName: FieldBackFillEnum
* @Description: 字段回填
* @Author: wanggeng
* @Date: 2022/5/11 17:38
* @Version: 1.0
*/
public enum FieldBackFillEnum {
NO_BACK_FILL("noBackFill", "不回填"),
CURRENT_USER_NAME("currentUserName", "当前用户昵称"),
CURRENT_USER_DEPARTMENT("currentUserDepartment", "当前用户部门");
private String value;
private String text;
FieldBackFillEnum(String value, String text) {
this.value = value;
this.text = text;
}
public String getValue() {
return value == null ? "" : value.trim();
}
public String getText() {
return text == null ? "" : text.trim();
}
}

View File

@ -27,10 +27,10 @@ public class NodeFormFieldVO {
private Boolean isEditable;
@ApiModelProperty(name = "isVisible", value = "是否可见")
private Boolean isVisible;
@ApiModelProperty(name = "editHistory", value = "编辑历史")
@ApiModelProperty(name = "editHistory", value = "签批类型(编辑历史")
private String editHistory;
@ApiModelProperty(name = "autoFillBack", value = "自动")
private String autoFillBack;
@ApiModelProperty(name = "autoBackFill", value = "自动")
private String autoBackFill;
public String getFieldId() {
return fieldId == null ? "" : fieldId.trim();
@ -96,12 +96,12 @@ public class NodeFormFieldVO {
this.editHistory = editHistory;
}
public String getAutoFillBack() {
return autoFillBack == null ? "" : autoFillBack.trim();
public String getAutoBackFill() {
return autoBackFill == null ? "" : autoBackFill.trim();
}
public void setAutoFillBack(String autoFillBack) {
this.autoFillBack = autoFillBack;
public void setAutoBackFill(String autoBackFill) {
this.autoBackFill = autoBackFill;
}
@Override
@ -123,8 +123,8 @@ public class NodeFormFieldVO {
.append(isVisible);
sb.append(",\"editHistory\":\"")
.append(editHistory).append('\"');
sb.append(",\"autoFillBack\":\"")
.append(autoFillBack).append('\"');
sb.append(",\"autoBackFill\":\"")
.append(autoBackFill).append('\"');
sb.append('}');
return sb.toString();
}

View File

@ -49,17 +49,31 @@ public interface IOaFormReportRouteService {
*/
void show(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
/**
* 打印
*
* @param formCode
* @param formVersion
* @param uid
* @param httpSession
* @param httpServletRequest
* @param httpServletResponse
*/
void print(String formCode, Integer formVersion, String uid, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
/**
* 查询页面
*
* @param formCode
* @param formVersion
* @param ccId
* @param httpSession
* @param httpServletRequest
* @param httpServletResponse
*/
void updateRead(String formCode, Integer formVersion, String ccId, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
/**
* APP新增页面
*

View File

@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.user.IUserBaseService;
import ink.wgink.module.activiti.enums.oa.TaskCommentTypeEnum;
import ink.wgink.module.activiti.pojo.bos.oa.TaskCommentBO;
import ink.wgink.module.activiti.pojo.dtos.oa.NodeButtonDTO;
import ink.wgink.module.activiti.pojo.dtos.oa.NodeFieldDTO;
import ink.wgink.module.activiti.pojo.pos.oa.OaNodeAssigneePO;
@ -12,8 +14,12 @@ import ink.wgink.module.activiti.pojo.vos.oa.page.*;
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
import ink.wgink.module.activiti.service.oa.*;
import ink.wgink.module.form.enums.design.FormTypeEnum;
import ink.wgink.module.form.pojo.pos.design.FormPO;
import ink.wgink.module.form.service.design.IFormDesignService;
import ink.wgink.module.form.service.design.IFormFieldService;
import ink.wgink.module.form.service.design.IFormService;
import ink.wgink.module.form.service.report.IFormReportRouteService;
import ink.wgink.module.form.service.report.IFormReportService;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.dtos.user.UserDTO;
import org.activiti.bpmn.model.FlowNode;
@ -22,8 +28,10 @@ import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@ -34,6 +42,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -70,6 +79,10 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
private INodeButtonService nodeButtonService;
@Autowired
private IOaCcService oaCcService;
@Autowired
private IFormService formService;
@Autowired
private IFormReportService formReportService;
@Override
public void save(String processDefinitionId, String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
@ -144,6 +157,77 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
formReportRouteService.show(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
@Override
public void print(String formCode, Integer formVersion, String uid, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
FormPO formPO = formService.getPOByCodeAndVersion(formCode, formVersion);
if (formPO == null) {
return;
}
// 处理附件文件视频音频签批等功能
Map<String, Object> reportForm = formReportService.get(formCode, formVersion, uid);
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().includeProcessVariables().processInstanceId(reportForm.get(IFormDesignService.PROCESS_INSTANCE_ID).toString()).singleResult();
if (historicProcessInstance == null) {
throw new SearchException("流程实例不存在");
}
// 设置签字
setSign(reportForm, historicProcessInstance);
// 设置会签
setJointlySign(reportForm);
formReportRouteService.setModal(formPO, reportForm);
formReportRouteService.showPage(reportForm, formCode, formPO.getPrintPageCode(), httpSession, httpServletRequest, httpServletResponse);
}
/**
* 设置签批
*
* @param reportForm
* @param historicProcessInstance
*/
private void setSign(Map<String, Object> reportForm, HistoricProcessInstance historicProcessInstance) {
Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
for (Map.Entry<String, Object> reportFormEntry : reportForm.entrySet()) {
Object signObject = processVariables.get(reportFormEntry.getKey() + IOaFormReportService.EDIT_SIGN_KEY_SUFFIX);
if (signObject != null) {
reportFormEntry.setValue(signObject);
}
}
}
/**
* 设置会签
*
* @param reportForm
*/
private void setJointlySign(Map<String, Object> reportForm) {
List<Comment> processInstanceComments = taskService.getProcessInstanceComments(reportForm.get(IFormDesignService.PROCESS_INSTANCE_ID).toString());
Map<String, String> jointlySignMap = new HashMap<>(16);
// 先处理会签字段
for (Comment comment : processInstanceComments) {
// 会签字段
if (!StringUtils.equals(TaskCommentTypeEnum.JOINTLY_SIGN.getValue(), comment.getType())) {
continue;
}
TaskCommentBO taskCommentBO = JSONObject.parseObject(comment.getFullMessage(), TaskCommentBO.class);
String jointlySignedValue = jointlySignMap.get(taskCommentBO.getFieldName());
if (jointlySignedValue == null) {
jointlySignedValue = "";
}
if (!jointlySignedValue.isEmpty()) {
jointlySignedValue += "\n";
}
jointlySignedValue += "签批人:" + taskCommentBO.getUserName() + "。签批内容:" + taskCommentBO.getContent() + "。签批时间:" + taskCommentBO.getTime();
jointlySignMap.put(taskCommentBO.getFieldName(), jointlySignedValue);
}
// 替换会签的内容
for (Map.Entry<String, Object> reportFormEntry : reportForm.entrySet()) {
String jointlySignValue = jointlySignMap.get(reportFormEntry.getKey());
if (StringUtils.isBlank(jointlySignValue)) {
continue;
}
reportFormEntry.setValue(jointlySignValue);
}
}
@Override
public void updateRead(String formCode, Integer formVersion, String ccId, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
oaCcService.updateRead(ccId, 1);
@ -187,7 +271,7 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
fieldVO.setIsEditable(nodeFieldDTO.getIsEditable());
fieldVO.setIsVisible(nodeFieldDTO.getIsVisible());
fieldVO.setEditHistory(nodeFieldDTO.getEditHistory());
nodeFieldDTO.getAutoBackFill();
fieldVO.setAutoBackFill(nodeFieldDTO.getAutoBackFill());
return fieldVO;
}).collect(Collectors.toList());
model.put("fields", JSONObject.toJSONString(fieldVOs));
@ -216,9 +300,11 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
if (StringUtils.isBlank(currentTaskId)) {
formButtonVO.setBtnGoBack(0);
formButtonVO.setBtnForcedEnd(0);
formButtonVO.setBtnPrint(0);
} else {
formButtonVO.setBtnGoBack(nodeButtonDTO.getBtnGoBack());
formButtonVO.setBtnForcedEnd(nodeButtonDTO.getBtnForcedEnd());
formButtonVO.setBtnPrint(nodeButtonDTO.getBtnPrint());
}
if (formButtonVO.getBtnGoBack() == 1) {
LOG.debug("存在回退按钮,查询历史节点");

View File

@ -30,8 +30,8 @@
`field_explain` varchar(255) DEFAULT NULL COMMENT '字段描述',
`is_visible` int(1) DEFAULT '1' COMMENT '是否可见',
`is_editable` int(1) DEFAULT '1' COMMENT '是否可编辑',
`editHistory` varchar(255) DEFAULT NULL COMMENT '编辑历史',
`auto_back_fill` varchar(255) DEFAULT NULL COMMENT '自动回填',
`editHistory` varchar(255) DEFAULT 'noRecord' COMMENT '编辑历史',
`auto_back_fill` varchar(255) DEFAULT 'noBackFill' COMMENT '自动回填',
PRIMARY KEY (`id`),
UNIQUE KEY `node_field_id` (`node_field_id`),
KEY `deployment_id` (`deployment_id`),
@ -106,6 +106,9 @@
</if>
<if test="editHistory != null and editHistory != ''">
edit_history = #{editHistory},
</if>
<if test="autoBackFill != null and autoBackFill != ''">
auto_back_fill = #{autoBackFill},
</if>
node_field_id = #{nodeFieldId}
WHERE

View File

@ -350,7 +350,8 @@
<td>
<select class="form-control input-sm" ng-model="formField.autoBackFill">
<option value="noBackFill">不回填</option>
<option value="currentUser">当前用户</option>
<option value="currentUserName" ng-if="formField.fieldTag == 'input'">当前用户昵称</option>
<option value="currentUserDepartment" ng-if="formField.fieldTag == 'input'">当前用户部门</option>
</select>
</td>
</tr>

View File

@ -1,5 +1,7 @@
package ink.wgink.module.form.service.report;
import ink.wgink.module.form.pojo.pos.design.FormPO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@ -27,6 +29,7 @@ public interface IFormReportRouteService {
/**
* 新增页面
*
* @param formCode
* @param formVersion
* @param httpSession
@ -151,4 +154,25 @@ public interface IFormReportRouteService {
* @param model
*/
void appShow(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> model);
/**
* 展示页面
*
* @param modal
* @param formCode
* @param pageCode
* @param httpSession
* @param httpServletRequest
* @param httpServletResponse
*/
void showPage(Map<String, Object> modal, String formCode, String pageCode, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
/**
* 设置model
*
* @param formPO
* @param modal
*/
void setModal(FormPO formPO, Map<String, Object> modal);
}

View File

@ -9,6 +9,7 @@ import ink.wgink.exceptions.base.SystemException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.form.enums.design.FormStatusEnum;
import ink.wgink.module.form.pojo.pos.design.FormPO;
import ink.wgink.module.form.service.design.IFormFieldService;
import ink.wgink.module.form.service.design.IFormService;
import ink.wgink.module.form.service.report.IFormReportRouteService;
import org.apache.commons.lang3.StringUtils;
@ -36,6 +37,8 @@ public class FormReportRouteServiceImpl extends DefaultBaseService implements IF
@Autowired
private IFormService formService;
@Autowired
private IFormFieldService formFieldService;
private Configuration configuration = new Configuration(Configuration.getVersion());
@PostConstruct
@ -181,7 +184,8 @@ public class FormReportRouteServiceImpl extends DefaultBaseService implements IF
* @param httpServletRequest
* @param httpServletResponse
*/
private void showPage(Map<String, Object> modal, String formCode, String pageCode, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
@Override
public void showPage(Map<String, Object> modal, String formCode, String pageCode, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
httpServletResponse.setContentType("text/html; charset=" + ISystemConstant.CHARSET_UTF8);
try {
Template template = getTemplate(formCode, pageCode);
@ -202,7 +206,8 @@ public class FormReportRouteServiceImpl extends DefaultBaseService implements IF
* @param modal
* @return
*/
private void setModal(FormPO formPO, Map<String, Object> modal) {
@Override
public void setModal(FormPO formPO, Map<String, Object> modal) {
modal.put("contextPath", httpServletRequest.getContextPath() + "/");
modal.put("formName", formPO.getFormName());
modal.put("formCode", formPO.getFormCode());

View File

@ -3,6 +3,7 @@ function OaFormUtil(layui) {
var win = $(window);
var layer = layui.layer;
var upload = layui.upload;
var form = layui.form;
var restAjax = layui.restajax;
var processImageEnlargeScale = 0;
@ -277,7 +278,41 @@ function OaFormUtil(layui) {
}
/**
* @description 禁止字段操作
* 初始化回填字段
* @param fields
* @param currentUser
*/
this.backFillFields = function(fields, currentUser) {
var obj = {};
for (var i = 0, item; item = fields[i++];) {
if(item.autoBackFill === 'currentUserName') {
obj[item.fieldName] = currentUser.userName;
continue;
}
if(item.autoBackFill === 'currentUserDepartment') {
if(currentUser.departments.length == 1) {
obj[item.fieldName] = currentUser.departments[0].departmentName;
continue;
}
if(currentUser.departments.length > 1) {
obj[item.fieldName] = currentUser.departments[0].departmentName;
var options = '';
for(var j = 0, jItem; jItem = currentUser.departments[j++];) {
options += '<option value="'+ jItem.departmentName +'">'+ jItem.departmentName +'</option>'
}
var parent = $('#'+ item.fieldName +'Block');
parent.empty();
parent.append('<select name="'+ item.fieldName +'">'+ options +'</select>');
continue;
}
}
}
form.val('dataForm', obj);
form.render(null, 'dataForm');
}
/**
* @description 禁止字段操作禁止操作的字段不参与提交
* @param fields {Array} [{fieldName:'', isEditable: 0|1}]
*/
this.disableFields = function (fields) {
@ -326,6 +361,9 @@ function OaFormUtil(layui) {
var isApp = opt.isApp;
var processInstanceId = opt.processInstanceId;
var taskId = opt.taskId;
var formCode = opt.formCode;
var formVersion = opt.formVersion;
var uid = opt.uid;
var onPreview = typeof (opt.onPreview) === 'function' ? opt.onPreview : null;
function initButton() {
@ -412,6 +450,7 @@ function OaFormUtil(layui) {
});
}
// 附件
$(document.body).on('click', '#showAttachmentBtn', function () {
var attachments = $('#attachments').val();
var attachmentArray = attachments.split(',');
@ -468,6 +507,7 @@ function OaFormUtil(layui) {
});
});
// 附件删除
$(document.body).on('click', '.delete-attachment-btn', function () {
var id = this.dataset.id;
var name = this.dataset.name;
@ -483,6 +523,7 @@ function OaFormUtil(layui) {
$(this).parent().parent().parent().remove();
});
// 附件预览
$(document.body).on('click', '.operation .preview-btn', function () {
var id = this.dataset.id;
var name = this.dataset.name;
@ -497,7 +538,15 @@ function OaFormUtil(layui) {
}
});
// 回退
// 打印
$(document.body).on('click', '#printBtn', function() {
if(!formCode || !formVersion || !uid) {
return;
}
window.open(restAjax.path('route/oa-form-report/print/code/{formCode}/version/{formVersion}/uid/{uid}', [formCode, formVersion, uid]), '_blank');
});
// 回退页面
$(document.body).on('click', '#goBackBtn', function () {
if (!taskId) {
return;

View File

@ -127,8 +127,11 @@
}
},
{field:'printPageCode', width:100, title: '打印代码', align:'center',
{field:'printPageCode', width:100, title: 'OA打印', align:'center',
templet: function(item) {
if(item.formType === 'default') {
return '-';
}
return '<div class="layui-btn-group">' +
'<button class="layui-btn layui-btn-xs" lay-event="printPageCodeEvent">打印页面</button>' +
'</div>';
@ -295,7 +298,7 @@
})
} else if(event === 'printPageCodeEvent') {
top.dialog.open({
title: '打印页面模板',
title: '打印页面模板【需要打印的内容添加到 startprint 与 endprint 之间,两个注释不能删除,变量用 ${XXX}占位(视频、音频、文件、附件只打印文件名称)】',
url: top.restAjax.path('route/form/get-print-page-code?formId={formId}&formCode={formCode}&formVersion={formVersion}', [data.formId, data.formCode, data.formVersion]),
width: '99%',
height: '99%',

View File

@ -4,29 +4,32 @@
<base href="${r'${contextPath}'}"/>
<meta charset="utf-8">
<title>${r'${formName}'}</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<style>
</style>
<!-- 这里写样式 -->
<style></style>
</head>
<body>
<div class="layui-anim layui-anim-fadein">
<div>
<!--startprint-->
<!-- 这里是打印位置 -->
<!--endprint-->
</div>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/'
}).extend({
index: 'lib/index'
}).use(['index'], function () {
});
function printPage() {
var bodyHtml = window.document.body.innerHTML
var sprnstr = '<!--startprint-->';
var eprnstr = '<!--endprint-->';
var printHtml = bodyHtml.substr(bodyHtml.indexOf(sprnstr) + 17);
printHtml = printHtml.substring(0, printHtml.indexOf(eprnstr));
window.document.body.innerHTML = printHtml;
window.print();
setTimeout(function() {
window.close();
}, 1000);
}
// 打印
printPage();
</script>
</body>
</html>

View File

@ -85,6 +85,9 @@
isApp:false,
processInstanceId: $('#processInstanceId').val(),
taskId: $('#taskId').val(),
formCode: $('#formCode').val(),
formVersion: $('#formVersion').val(),
uid: uid,
onPreview: function(obj) {
// 这里写预览的逻辑,没有不写此方法
// console.log(obj);