package com.mossle.operation.web;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.mossle.api.form.FormConnector;
import com.mossle.api.form.FormDTO;
import com.mossle.api.humantask.HumanTaskConnector;
import com.mossle.api.humantask.HumanTaskDefinition;
import com.mossle.api.keyvalue.FormParameter;
import com.mossle.api.keyvalue.KeyValueConnector;
import com.mossle.api.keyvalue.Prop;
import com.mossle.api.keyvalue.Record;
import com.mossle.api.keyvalue.RecordBuilder;
import com.mossle.api.process.ProcessConnector;
import com.mossle.api.process.ProcessDTO;
import com.mossle.api.store.StoreConnector;
import com.mossle.api.tenant.TenantHolder;
import com.mossle.api.user.UserConnector;
import com.mossle.button.ButtonDTO;
import com.mossle.button.ButtonHelper;
import com.mossle.core.MultipartHandler;
import com.mossle.core.auth.CurrentUserHolder;
import com.mossle.core.mapper.JsonMapper;
import com.mossle.core.page.Page;
import com.mossle.core.spring.MessageHelper;
import com.mossle.operation.service.OperationService;
import com.mossle.xform.Xform;
import com.mossle.xform.XformBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartResolver;
/**
* 流程操作.
*
* @author Lingo
*/
@Controller
@RequestMapping("operation")
public class ProcessOperationController {
private static Logger logger = LoggerFactory
.getLogger(ProcessOperationController.class);
public static final int STATUS_DRAFT_PROCESS = 0;
public static final int STATUS_DRAFT_TASK = 1;
public static final int STATUS_RUNNING = 2;
private OperationService operationService;
private KeyValueConnector keyValueConnector;
private MessageHelper messageHelper;
private CurrentUserHolder currentUserHolder;
private ProcessConnector processConnector;
private HumanTaskConnector humanTaskConnector;
private MultipartResolver multipartResolver;
private StoreConnector storeConnector;
private ButtonHelper buttonHelper = new ButtonHelper();
private FormConnector formConnector;
private JsonMapper jsonMapper = new JsonMapper();
private TenantHolder tenantHolder;
private UserConnector userConnector;
/**
* 保存草稿.
*/
@RequestMapping("process-operation-saveDraft")
public String saveDraft(HttpServletRequest request) throws Exception {
this.doSaveRecord(request);
return "operation/process-operation-saveDraft";
}
/**
* 列出所有草稿.
*/
@RequestMapping("process-operation-listDrafts")
public String listDrafts(@ModelAttribute Page page, Model model)
throws Exception {
String userId = currentUserHolder.getUserId();
String tenantId = tenantHolder.getTenantId();
page = keyValueConnector.pagedQuery(page, STATUS_DRAFT_PROCESS, userId,
tenantId);
model.addAttribute("page", page);
return "operation/process-operation-listDrafts";
}
/**
* 删除草稿.
*/
@RequestMapping("process-operation-removeDraft")
public String removeDraft(@RequestParam("code") String code) {
keyValueConnector.removeByCode(code);
return "redirect:/operation/process-operation-listDrafts.do";
}
/**
* 显示启动流程的表单.
*/
@RequestMapping("process-operation-viewStartForm")
public String viewStartForm(
HttpServletRequest request,
@RequestParam("bpmProcessId") String bpmProcessId,
@RequestParam(value = "businessKey", required = false) String businessKey,
Model model) throws Exception {
String tenantId = tenantHolder.getTenantId();
FormParameter formParameter = new FormParameter();
formParameter.setBpmProcessId(bpmProcessId);
formParameter.setBusinessKey(businessKey);
ProcessDTO processDto = processConnector.findProcess(bpmProcessId);
String processDefinitionId = processDto.getProcessDefinitionId();
FormDTO formDto = this.processConnector
.findStartForm(processDefinitionId);
formParameter.setFormDto(formDto);
if (formDto.isExists()) {
if (formDto.isRedirect()) {
// 如果是外部表单,就直接跳转出去
String redirectUrl = formDto.getUrl() + "?processDefinitionId="
+ formDto.getProcessDefinitionId();
return "redirect:" + redirectUrl;
}
// 如果找到了form,就显示表单
if (processDto.isConfigTask()) {
// 如果需要配置负责人
formParameter.setNextStep("taskConf");
} else {
formParameter.setNextStep("confirmStartProcess");
}
return this.doViewStartForm(formParameter, model, tenantId);
} else if (processDto.isConfigTask()) {
formParameter.setProcessDefinitionId(processDefinitionId);
// 如果没找到form,就判断是否配置负责人
return this.doTaskConf(formParameter, model);
} else {
// 如果也不需要配置任务,就直接进入确认发起流程
return this.doConfirmStartProcess(formParameter, model);
}
}
/**
* 配置每个任务的参与人.
*
* 如果是执行taskConf,可能是填写表单,也可能是直接进入taskConf。
*/
@RequestMapping("process-operation-taskConf")
public String taskConf(HttpServletRequest request, Model model)
throws Exception {
FormParameter formParameter = this.doSaveRecord(request);
ProcessDTO processDto = processConnector.findProcess(formParameter
.getBpmProcessId());
String processDefinitionId = processDto.getProcessDefinitionId();
formParameter.setProcessDefinitionId(processDefinitionId);
if (processDto.isConfigTask()) {
// 如果需要配置负责人
formParameter.setNextStep("confirmStartProcess");
return this.doTaskConf(formParameter, model);
} else {
// 如果不需要配置负责人,就进入确认发起流程的页面
return this.doConfirmStartProcess(formParameter, model);
}
}
/**
* 确认发起流程.
*/
@RequestMapping("process-operation-confirmStartProcess")
public String confirmStartProcess(HttpServletRequest request, Model model)
throws Exception {
FormParameter formParameter = this.doSaveRecord(request);
formParameter.setNextStep("startProcessInstance");
this.doConfirmStartProcess(formParameter, model);
return "operation/process-operation-confirmStartProcess";
}
/**
* 发起流程.
*/
@RequestMapping("process-operation-startProcessInstance")
public String startProcessInstance(HttpServletRequest request, Model model)
throws Exception {
FormParameter formParameter = this.doSaveRecord(request);
this.doConfirmStartProcess(formParameter, model);
Record record = keyValueConnector.findByCode(formParameter
.getBusinessKey());
ProcessDTO processDto = processConnector.findProcess(formParameter
.getBpmProcessId());
String processDefinitionId = processDto.getProcessDefinitionId();
// 获得form的信息
FormDTO formDto = processConnector.findStartForm(processDefinitionId);
Xform xform = new XformBuilder().setStoreConnector(storeConnector)
.setUserConnector(userConnector)
.setContent(formDto.getContent()).setRecord(record).build();
Map<String, Object> processParameters = xform.getMapData();
logger.info("processParameters : {}", processParameters);
// String processInstanceId = processConnector.startProcess(
// currentUserHolder.getUserId(), formParameter.getBusinessKey(),
// processDefinitionId, processParameters);
// record = new RecordBuilder().build(record, STATUS_RUNNING,
// processInstanceId);
// keyValueConnector.save(record);
String userId = currentUserHolder.getUserId();
String businessKey = formParameter.getBusinessKey();
this.operationService.startProcessInstance(userId, businessKey,
processDefinitionId, processParameters, record);
return "operation/process-operation-startProcessInstance";
}
// ~ ======================================================================
/**
* 通过multipart请求构建formParameter.
*/
public FormParameter buildFormParameter(MultipartHandler multipartHandler) {
FormParameter formParameter = new FormParameter();
formParameter.setMultiValueMap(multipartHandler.getMultiValueMap());
formParameter.setMultiFileMap(multipartHandler.getMultiFileMap());
formParameter.setBusinessKey(multipartHandler.getMultiValueMap()
.getFirst("businessKey"));
formParameter.setBpmProcessId(multipartHandler.getMultiValueMap()
.getFirst("bpmProcessId"));
formParameter.setHumanTaskId(multipartHandler.getMultiValueMap()
.getFirst("humanTaskId"));
return formParameter;
}
/**
* 把数据先保存到keyvalue里.
*/
public FormParameter doSaveRecord(HttpServletRequest request)
throws Exception {
String userId = currentUserHolder.getUserId();
String tenantId = tenantHolder.getTenantId();
MultipartHandler multipartHandler = new MultipartHandler(
multipartResolver);
FormParameter formParameter = null;
try {
multipartHandler.handle(request);
logger.debug("multiValueMap : {}",
multipartHandler.getMultiValueMap());
logger.debug("multiFileMap : {}",
multipartHandler.getMultiFileMap());
formParameter = this.buildFormParameter(multipartHandler);
String businessKey = operationService.saveDraft(userId, tenantId,
formParameter);
if ((formParameter.getBusinessKey() == null)
|| "".equals(formParameter.getBusinessKey().trim())) {
formParameter.setBusinessKey(businessKey);
}
Record record = keyValueConnector.findByCode(businessKey);
record = new RecordBuilder().build(record, multipartHandler,
storeConnector, tenantId);
keyValueConnector.save(record);
} finally {
multipartHandler.clear();
}
return formParameter;
}
/**
* 实际确认发起流程.
*/
public String doConfirmStartProcess(FormParameter formParameter, Model model) {
humanTaskConnector.configTaskDefinitions(
formParameter.getBusinessKey(),
formParameter.getList("taskDefinitionKeys"),
formParameter.getList("taskAssignees"));
model.addAttribute("businessKey", formParameter.getBusinessKey());
model.addAttribute("nextStep", formParameter.getNextStep());
model.addAttribute("bpmProcessId", formParameter.getBpmProcessId());
return "operation/process-operation-confirmStartProcess";
}
/**
* 实际显示开始表单.
*/
public String doViewStartForm(FormParameter formParameter, Model model,
String tenantId) throws Exception {
model.addAttribute("formDto", formParameter.getFormDto());
model.addAttribute("bpmProcessId", formParameter.getBpmProcessId());
model.addAttribute("businessKey", formParameter.getBusinessKey());
model.addAttribute("nextStep", formParameter.getNextStep());
List<ButtonDTO> buttons = new ArrayList<ButtonDTO>();
buttons.add(buttonHelper.findButton("saveDraft"));
buttons.add(buttonHelper.findButton(formParameter.getNextStep()));
model.addAttribute("buttons", buttons);
model.addAttribute("formDto", formParameter.getFormDto());
String json = this.findStartFormData(formParameter.getBusinessKey());
if (json != null) {
model.addAttribute("json", json);
}
Record record = keyValueConnector.findByCode(formParameter
.getBusinessKey());
FormDTO formDto = formConnector.findForm(formParameter.getFormDto()
.getCode(), tenantId);
if (record != null) {
Xform xform = new XformBuilder().setStoreConnector(storeConnector)
.setUserConnector(userConnector)
.setContent(formDto.getContent()).setRecord(record).build();
model.addAttribute("xform", xform);
} else {
Xform xform = new XformBuilder().setStoreConnector(storeConnector)
.setUserConnector(userConnector)
.setContent(formDto.getContent()).build();
model.addAttribute("xform", xform);
}
return "operation/process-operation-viewStartForm";
}
/**
* 实际展示配置任务的配置.
*/
public String doTaskConf(FormParameter formParameter, Model model) {
model.addAttribute("bpmProcessId", formParameter.getBpmProcessId());
model.addAttribute("businessKey", formParameter.getBusinessKey());
model.addAttribute("nextStep", formParameter.getNextStep());
List<HumanTaskDefinition> humanTaskDefinitions = humanTaskConnector
.findHumanTaskDefinitions(formParameter
.getProcessDefinitionId());
model.addAttribute("humanTaskDefinitions", humanTaskDefinitions);
return "operation/process-operation-taskConf";
}
/**
* 读取草稿箱中的表单数据,转换成json.
*/
public String findStartFormData(String businessKey) throws Exception {
Record record = keyValueConnector.findByCode(businessKey);
if (record == null) {
return null;
}
Map map = new HashMap();
for (Prop prop : record.getProps().values()) {
map.put(prop.getCode(), prop.getValue());
}
String json = jsonMapper.toJson(map);
return json;
}
// ~ ======================================================================
@Resource
public void setKeyValueConnector(KeyValueConnector keyValueConnector) {
this.keyValueConnector = keyValueConnector;
}
@Resource
public void setMessageHelper(MessageHelper messageHelper) {
this.messageHelper = messageHelper;
}
@Resource
public void setCurrentUserHolder(CurrentUserHolder currentUserHolder) {
this.currentUserHolder = currentUserHolder;
}
@Resource
public void setOperationService(OperationService operationService) {
this.operationService = operationService;
}
@Resource
public void setProcessConnector(ProcessConnector processConnector) {
this.processConnector = processConnector;
}
@Resource
public void setHumanTaskConnector(HumanTaskConnector humanTaskConnector) {
this.humanTaskConnector = humanTaskConnector;
}
@Resource
public void setMultipartResolver(MultipartResolver multipartResolver) {
this.multipartResolver = multipartResolver;
}
@Resource
public void setStoreConnector(StoreConnector storeConnector) {
this.storeConnector = storeConnector;
}
@Resource
public void setFormConnector(FormConnector formConnector) {
this.formConnector = formConnector;
}
@Resource
public void setTenantHolder(TenantHolder tenantHolder) {
this.tenantHolder = tenantHolder;
}
@Resource
public void setUserConnector(UserConnector userConnector) {
this.userConnector = userConnector;
}
}