package com.mossle.form.web;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mossle.api.form.FormConnector;
import com.mossle.api.form.FormDTO;
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.store.StoreConnector;
import com.mossle.api.tenant.TenantHolder;
import com.mossle.api.user.UserConnector;
import com.mossle.core.MultipartHandler;
import com.mossle.core.auth.CurrentUserHolder;
import com.mossle.core.export.Exportor;
import com.mossle.core.export.TableModel;
import com.mossle.core.mapper.BeanMapper;
import com.mossle.core.mapper.JsonMapper;
import com.mossle.core.page.Page;
import com.mossle.core.query.PropertyFilter;
import com.mossle.core.spring.MessageHelper;
import com.mossle.form.persistence.domain.FormTemplate;
import com.mossle.form.persistence.manager.FormTemplateManager;
import com.mossle.form.xform.Xform;
import com.mossle.form.xform.XformBuilder;
import org.apache.commons.lang3.StringUtils;
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;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
@RequestMapping("form")
public class FormDataController {
private static Logger logger = LoggerFactory
.getLogger(FormDataController.class);
public static final int TEST = -1;
private FormTemplateManager formTemplateManager;
private Exportor exportor;
private BeanMapper beanMapper = new BeanMapper();
private JsonMapper jsonMapper = new JsonMapper();
private MessageHelper messageHelper;
private MultipartResolver multipartResolver;
private TenantHolder tenantHolder;
private CurrentUserHolder currentUserHolder;
private KeyValueConnector keyValueConnector;
private StoreConnector storeConnector;
private FormConnector formConnector;
private UserConnector userConnector;
/**
* 列出所有草稿.
*/
@RequestMapping("form-data-list")
public String list(@ModelAttribute Page page, Model model) throws Exception {
String userId = currentUserHolder.getUserId();
String tenantId = tenantHolder.getTenantId();
page = keyValueConnector.pagedQuery(page, TEST, tenantId, tenantId);
model.addAttribute("page", page);
return "form/form-data-list";
}
@RequestMapping("form-data-input")
public String input(
@RequestParam(value = "businessKey", required = false) String businessKey,
@RequestParam("category") String category, Model model)
throws Exception {
if (businessKey != null) {
String tenantId = tenantHolder.getTenantId();
FormParameter formParameter = new FormParameter();
formParameter.setBpmProcessId(category);
formParameter.setBusinessKey(businessKey);
// FormDTO formDto = this.processConnector
// .findStartForm(processDefinitionId);
FormTemplate formTemplate = formTemplateManager.findUniqueBy(
"code", category);
FormDTO formDto = new FormDTO();
formDto.setContent(formTemplate.getContent());
formDto.setCode(formTemplate.getCode());
formParameter.setFormDto(formDto);
if (formDto.isExists()) {
if (formDto.isRedirect()) {
// 如果是外部表单,就直接跳转出去
String redirectUrl = formDto.getUrl()
+ "?processDefinitionId="
+ formDto.getProcessDefinitionId();
return "redirect:" + redirectUrl;
}
return this.doViewStartForm(formParameter, model, tenantId);
}
} else {
String tenantId = tenantHolder.getTenantId();
FormDTO formDto = formConnector.findForm(category, tenantId);
Xform xform = new XformBuilder().setStoreConnector(storeConnector)
.setContent(formDto.getContent()).build();
model.addAttribute("xform", xform);
model.addAttribute("bpmProcessId", category);
}
return "form/form-data-input";
}
@RequestMapping("form-data-save")
public String save(HttpServletRequest request,
RedirectAttributes redirectAttributes) 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 = this.saveDraft(tenantId, tenantId,
formParameter);
if ((formParameter.getBusinessKey() == null)
|| "".equals(formParameter.getBusinessKey().trim())) {
formParameter.setBusinessKey(businessKey);
}
Record record = keyValueConnector.findByCode(businessKey);
if (record != null) {
record = new RecordBuilder().build(record, multipartHandler,
storeConnector, tenantId);
keyValueConnector.save(record);
}
} finally {
multipartHandler.clear();
}
return "redirect:/form/form-data-list.do";
}
@RequestMapping("form-data-remove")
public String remove(@RequestParam("code") String code,
RedirectAttributes redirectAttributes) {
keyValueConnector.removeByCode(code);
messageHelper.addFlashMessage(redirectAttributes,
"core.success.delete", "删除成功");
return "redirect:/form/form-data-list.do";
}
// ~ ======================================================================
/**
* 通过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;
}
/**
* 保存草稿.
*/
public String saveDraft(String userId, String tenantId,
FormParameter formParameter) {
String humanTaskId = formParameter.getHumanTaskId();
String businessKey = formParameter.getBusinessKey();
String bpmProcessId = formParameter.getBpmProcessId();
if (StringUtils.isNotBlank(businessKey)) {
// 如果是流程草稿,直接通过businessKey获得record,更新数据
Record record = keyValueConnector.findByCode(businessKey);
record = new RecordBuilder().build(record, TEST, formParameter);
keyValueConnector.save(record);
} else if (StringUtils.isNotBlank(bpmProcessId)) {
// 如果是第一次保存草稿,肯定是流程草稿,先初始化record,再保存数据
Record record = new RecordBuilder().build(bpmProcessId, TEST,
formParameter, userId, tenantId);
// ProcessDTO processDto = processConnector.findProcess(bpmProcessId);
// record.setName(processDto.getProcessDefinitionName());
record.setName(bpmProcessId);
keyValueConnector.save(record);
businessKey = record.getCode();
if (record.getBusinessKey() == null) {
record.setBusinessKey(businessKey);
keyValueConnector.save(record);
}
} else {
logger.error(
"humanTaskId, businessKey, bpmProcessId all null : {}",
formParameter.getMultiValueMap());
throw new IllegalArgumentException(
"humanTaskId, businessKey, bpmProcessId all null");
}
return businessKey;
}
/**
* 实际显示开始表单.
*/
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 "form/form-data-input";
}
/**
* 读取草稿箱中的表单数据,转换成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 setFormTemplateManager(FormTemplateManager formTemplateManager) {
this.formTemplateManager = formTemplateManager;
}
@Resource
public void setExportor(Exportor exportor) {
this.exportor = exportor;
}
@Resource
public void setMessageHelper(MessageHelper messageHelper) {
this.messageHelper = messageHelper;
}
@Resource
public void setMultipartResolver(MultipartResolver multipartResolver) {
this.multipartResolver = multipartResolver;
}
@Resource
public void setTenantHolder(TenantHolder tenantHolder) {
this.tenantHolder = tenantHolder;
}
@Resource
public void setCurrentUserHolder(CurrentUserHolder currentUserHolder) {
this.currentUserHolder = currentUserHolder;
}
@Resource
public void setKeyValueConnector(KeyValueConnector keyValueConnector) {
this.keyValueConnector = keyValueConnector;
}
@Resource
public void setStoreConnector(StoreConnector storeConnector) {
this.storeConnector = storeConnector;
}
@Resource
public void setFormConnector(FormConnector formConnector) {
this.formConnector = formConnector;
}
@Resource
public void setUserConnector(UserConnector userConnector) {
this.userConnector = userConnector;
}
}