/* * Copyright 2015-2016 http://hsweb.me * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hsweb.web.controller.form; import org.hsweb.ezorm.core.OptionConverter; import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData; import org.hsweb.ezorm.rdb.meta.RDBTableMetaData; import org.hsweb.web.bean.common.QueryParam; import org.hsweb.web.bean.common.UpdateMapParam; import org.hsweb.web.bean.po.form.Form; import org.hsweb.web.bean.po.user.User; import org.hsweb.web.core.authorize.annotation.Authorize; import org.hsweb.web.core.exception.BusinessException; import org.hsweb.web.core.exception.NotFoundException; import org.hsweb.web.core.logger.annotation.AccessLogger; import org.hsweb.web.core.message.ResponseMessage; import org.hsweb.web.service.form.DynamicFormService; import org.hsweb.web.service.form.FormService; import org.hsweb.web.service.resource.FileService; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; /** * 动态表单管理控制器,用于操作动态表单以及对表单数据的增删改查和excel导入导出 * 将使用{@link org.hsweb.web.controller.DynamicFormAuthorizeValidator#validate(String, User, Map, String...)}进行权限验证 * * @author zhouhao */ @RestController @RequestMapping(value = "/dyn-form") @AccessLogger("动态表单") public class DynamicFormController { /** * 动态表单服务类 */ @Resource private DynamicFormService dynamicFormService; /** * 表单管理服务类 */ @Resource private FormService formService; /** * 文件服务类 */ @Resource private FileService fileService; /** * 根据表单名称,获取已发布此名称的表单信息 * * @param name 表单名称 * @return 表单数据 * @throws NotFoundException 如果表达不存在或未部署将可能抛出此异常 */ @RequestMapping(value = "/deployed/{name}", method = RequestMethod.GET) @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'R')") @AccessLogger("查询发布表单") public ResponseMessage deployed(@PathVariable("name") String name) { return ResponseMessage.ok(formService.selectDeployed(name)); } /** * 根据版本获取表单信息 * * @param name 表单名称 * @param version 版本 * @return 表单信息 * @throws NotFoundException 表单不存在时 抛出此异常 */ @RequestMapping(value = "/{name}/v/{version}", method = RequestMethod.GET) @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'R')") @AccessLogger("根据版本获取表单") public ResponseMessage selectByVersion(@PathVariable(value = "name") String name, @PathVariable(value = "version") Integer version) { Form form = formService.selectByVersion(name, version); if (form == null) throw new NotFoundException("表单不存在"); return ResponseMessage.ok(form); } /** * 根据表单名称和查询参数,查询表单的数据列表 * * @param name 表单名称 * @param param 查询参数{@link QueryParam} * @return 如果查询参数指定不分页, 将返回格式:[{},{}...].如果指定分页,将返回:{total:数据总数,data:[{},{},...]} * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}", method = RequestMethod.GET) @AccessLogger("查看数据列表") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'R')") public ResponseMessage list(@PathVariable("name") String name, QueryParam param) throws SQLException { // 获取条件查询 Object data; if (!param.isPaging())//不分页 data = dynamicFormService.select(name, param); else data = dynamicFormService.selectPager(name, param); return ResponseMessage.ok(data) .onlyData(); } /** * 根据表单名称和查询参数,查询表单的数据数量 * * @param name 表单名称 * @param param 查询参数{@link QueryParam} * @return 查询结果 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}/total", method = RequestMethod.GET) @AccessLogger("查看数据数量") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'R')") public ResponseMessage total(@PathVariable("name") String name, QueryParam param) throws SQLException { return ResponseMessage.ok(dynamicFormService.total(name, param)); } /** * 根据表单名和主键值查询数据 * * @param name 表单名称 * @param primaryKey 主键值 * @return 查询结果 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}/{primaryKey}", method = RequestMethod.GET) @AccessLogger("按主键查询数据") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'R')") public ResponseMessage info(@PathVariable("name") String name, @PathVariable("primaryKey") String primaryKey) throws SQLException { Map<String, Object> data = dynamicFormService.selectByPk(name, primaryKey); return ResponseMessage.ok(data); } /** * 向指定名称的表单中新增一条数据 * * @param name 表单名称 * @param data 数据 * @return 新增成功后返回被新增数据的主键值 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 * @throws org.hsweb.ezorm.rdb.exception.ValidationException 数据格式验证失败时抛出此异常 */ @RequestMapping(value = "/{name}", method = RequestMethod.POST) @AccessLogger("新增数据") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'C')") public ResponseMessage insert(@PathVariable("name") String name, @RequestBody Map<String, Object> data) throws SQLException { String pk = dynamicFormService.insert(name, data); return ResponseMessage.ok(pk); } /** * 更新指定名称的表单中指定主键对应的数据 * * @param name 表单名称 * @param primaryKey 数据主键值 * @param data 数据 * @return 更新记录数量 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 * @throws org.hsweb.ezorm.rdb.exception.ValidationException 数据格式验证失败时抛出此异常 */ @RequestMapping(value = "/{name}/{primaryKey}", method = RequestMethod.PUT) @AccessLogger("更新数据") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'U')") public ResponseMessage update(@PathVariable("name") String name, @PathVariable("primaryKey") String primaryKey, @RequestBody(required = true) Map<String, Object> data) throws SQLException { int i = dynamicFormService.updateByPk(name, primaryKey, new UpdateMapParam(data)); return ResponseMessage.ok(i); } /** * 从指定名称的表单中根据主键值删除数据 * * @param name 表单名称 * @param primaryKey 主键值 * @return 删除成功通知 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}/{primaryKey}", method = RequestMethod.DELETE) @AccessLogger("删除数据") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'D')") public ResponseMessage delete(@PathVariable("name") String name, @PathVariable("primaryKey") String primaryKey) throws SQLException { dynamicFormService.deleteByPk(name, primaryKey); return ResponseMessage.ok(); } /** * 从指定名称的表单中导出excel (.xlsx) * * @param name 表单名称 * @param fileName 导出后的文件名 * @param queryParam 导出数据查询参数{@link QueryParam} * @param response {@link HttpServletResponse} * @throws Exception excel导出异常 * @throws SQLException 执行查询sql错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}/export/{fileName:.+}", method = RequestMethod.GET) @AccessLogger("导出excel") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'export')") public void exportExcel(@PathVariable("name") String name, @PathVariable("fileName") String fileName, QueryParam queryParam, HttpServletResponse response) throws Exception { response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); response.setContentType("application/vnd.ms-excel"); dynamicFormService.exportExcel(name, queryParam, response.getOutputStream()); } /** * 向指定名称的表单中导入excel数据.excel支持(xls,xlsx). * 如果某条数据导入失败,将不会回滚,而是记录错误原因. * * @param name 表单名称 * @param fileId 文件id,通过{@link org.hsweb.web.controller.file.FileController#upload(MultipartFile[])} 上传后获得 * 使用,分割可实现同时导入多个文件 * @return 导入结果, 格式参照:{@link DynamicFormService#importExcel(String, InputStream)} * @throws IOException 读取excel文件错误 * @throws BusinessException 解析excel文件错误 * @throws NotFoundException 表单不存在或在未发布 */ @RequestMapping(value = "/{name}/import/{fileId:.+}", method = {RequestMethod.PATCH}) @AccessLogger("导入excel") @Authorize(expression = "#dynamicFormAuthorizeValidator.validate(#name,#user,#paramsMap,'import')") public ResponseMessage importExcel(@PathVariable("name") String name, @PathVariable("fileId") String fileId) throws IOException { String[] ids = fileId.split("[,]"); Map<String, Object> result = new HashMap<>(); for (int i = 0; i < ids.length; i++) { try (InputStream inputStream = fileService.readResources(ids[i])) { result.put(ids[i], dynamicFormService.importExcel(name, inputStream)); } } return ResponseMessage.ok(result); } /** * 数据字典映射:将指定的数据映射为数据字典对应的数据。<br> * 如: 表单{name}的字段{field}的字典配置为 [{"男":"1"},{"女":"0"}];<br> * 传入参数type=1,data=男,得到结果 {data:"1"}。传入参数 type!=1,data=1.得到结果{data:"男"} * * @param name 表单名称 * @param field 字段 * @param data 要映射的数据 * @param type 映射的类型 ,1或其他值,当为1时,将key映射为value,其他则将value映射为key。 * @return 映射结果 * @throws NotFoundException 表单或字段不存在 */ @RequestMapping(value = "/{name}/{field}/{type}/{data:.+}") @AccessLogger("数据字典映射") @Authorize public ResponseMessage mapperOption(@PathVariable("name") String name, @PathVariable("field") String field, @PathVariable("data") String data, @PathVariable("type") String type) { try { RDBTableMetaData metaData = dynamicFormService.getDefaultDatabase().getTable(name).getMeta(); RDBColumnMetaData fieldMetaData = metaData.findColumn(field); if (fieldMetaData == null) throw new NullPointerException(); OptionConverter converter = fieldMetaData.getOptionConverter(); if (converter == null) return ResponseMessage.ok(data); switch (type) { case "1": return ResponseMessage.ok(converter.converterData(data)); default: return ResponseMessage.ok(converter.converterValue(data)); } } catch (NullPointerException e) { throw new NotFoundException("字段不存在"); } } }