b37ef100baaca32d74f591b79b4d285587afb367.svn-base 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. package org.jeecg.modules.online.cgreport.controller;
  2. import java.io.UnsupportedEncodingException;
  3. import java.math.BigDecimal;
  4. import java.net.URLDecoder;
  5. import java.util.Collection;
  6. import java.util.Collections;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Map.Entry;
  11. import java.util.Set;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import com.alibaba.fastjson.JSONArray;
  15. import com.alibaba.fastjson.JSONObject;
  16. import org.apache.commons.lang.ArrayUtils;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.jeecg.common.api.vo.Result;
  19. import org.jeecg.common.aspect.annotation.AutoLog;
  20. import org.jeecg.common.system.base.controller.JeecgController;
  21. import org.jeecg.common.system.query.QueryGenerator;
  22. import org.jeecg.modules.online.cgreport.entity.ChartsData;
  23. import org.jeecg.modules.online.cgreport.entity.CommonConstants;
  24. import org.jeecg.modules.online.cgreport.entity.DiagramConfiguration;
  25. import org.jeecg.modules.online.cgreport.entity.DiagramFieldConfiguration;
  26. import org.jeecg.modules.online.cgreport.service.IDiagramConfigurationService;
  27. import org.jeecg.modules.online.cgreport.service.IDiagramFieldConfigurationService;
  28. import org.jeecg.modules.system.util.OnlineUtil;
  29. import org.springframework.beans.factory.annotation.Autowired;
  30. import org.springframework.transaction.annotation.Transactional;
  31. import org.springframework.web.bind.annotation.PostMapping;
  32. import org.springframework.web.bind.annotation.GetMapping;
  33. import org.springframework.web.bind.annotation.PostMapping;
  34. import org.springframework.web.bind.annotation.PostMapping;
  35. import org.springframework.web.bind.annotation.RequestBody;
  36. import org.springframework.web.bind.annotation.RequestMapping;
  37. import org.springframework.web.bind.annotation.RequestMethod;
  38. import org.springframework.web.bind.annotation.RequestParam;
  39. import org.springframework.web.bind.annotation.RestController;
  40. import org.springframework.web.servlet.ModelAndView;
  41. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  42. import com.baomidou.mybatisplus.core.metadata.IPage;
  43. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  44. import com.googlecode.aviator.AviatorEvaluator;
  45. import com.googlecode.aviator.Expression;
  46. import io.swagger.annotations.Api;
  47. import io.swagger.annotations.ApiOperation;
  48. import lombok.extern.slf4j.Slf4j;
  49. /**
  50. * @Description: 图表配置
  51. */
  52. @Slf4j
  53. @Api(tags = "图表配置")
  54. @RestController
  55. @RequestMapping("/diagram/diagramConfiguration")
  56. public class DiagramConfigurationController
  57. extends JeecgController<DiagramConfiguration, IDiagramConfigurationService> {
  58. @Autowired
  59. private IDiagramConfigurationService diagramConfigurationService;
  60. @Autowired
  61. private IDiagramFieldConfigurationService diagramFieldConfigurationService;
  62. /**
  63. * 分页列表查询
  64. *
  65. * @param diagramConfiguration
  66. * @param pageNo
  67. * @param pageSize
  68. * @param req
  69. * @return
  70. */
  71. @AutoLog(value = "图表配置-分页列表查询")
  72. @ApiOperation(value = "图表配置-分页列表查询", notes = "图表配置-分页列表查询")
  73. @GetMapping(value = "/list")
  74. public Result<?> queryPageList(DiagramConfiguration diagramConfiguration,
  75. @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
  76. @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
  77. QueryWrapper<DiagramConfiguration> queryWrapper = QueryGenerator.initQueryWrapper(diagramConfiguration, req.getParameterMap());
  78. Page<DiagramConfiguration> page = new Page<DiagramConfiguration>(pageNo, pageSize);
  79. IPage<DiagramConfiguration> pageList = diagramConfigurationService.page(page, queryWrapper);
  80. List<DiagramConfiguration> records = pageList.getRecords();
  81. if (records != null && !records.isEmpty()) {
  82. for (DiagramConfiguration record : records) {
  83. QueryWrapper<DiagramFieldConfiguration> qw = new QueryWrapper<DiagramFieldConfiguration>();
  84. qw.eq("DIAGRAM_CODE", record.getCode()).orderByAsc("ORDER_NUM");
  85. List<DiagramFieldConfiguration> diagramFieldConfigurationList = this.diagramFieldConfigurationService
  86. .list(qw);
  87. record.setDiagramFieldConfigurationList(diagramFieldConfigurationList);
  88. }
  89. }
  90. return Result.OK(pageList);
  91. }
  92. /**
  93. * 添加
  94. *
  95. * @param diagramConfiguration
  96. * @return
  97. */
  98. @AutoLog(value = "图表配置-添加")
  99. @ApiOperation(value = "图表配置-添加", notes = "图表配置-添加")
  100. @PostMapping(value = "/add")
  101. public Result<?> add(@RequestBody DiagramConfiguration diagramConfiguration) {
  102. // 校验code是否重复
  103. Result<?> result = this.duplicateCheck(diagramConfiguration.getCode());
  104. if (result != null) {
  105. return result;
  106. }
  107. // 保存主表信息
  108. try {
  109. this.diagramConfigurationService.add(diagramConfiguration);
  110. } catch (Exception e) {
  111. e.printStackTrace();
  112. log.error(CommonConstants.MSG_ERROR_OPERATE, e);
  113. return Result.error(e.getMessage());
  114. }
  115. // 渲染客户端
  116. return Result.OK(CommonConstants.MSG_SUCCESS_ADD, null);
  117. }
  118. /**
  119. * 编辑
  120. *
  121. * @param diagramConfiguration
  122. * @return
  123. */
  124. @AutoLog(value = "图表配置-编辑")
  125. @ApiOperation(value = "图表配置-编辑", notes = "图表配置-编辑")
  126. @PostMapping(value = "/edit")
  127. public Result<?> edit(@RequestBody DiagramConfiguration diagramConfiguration) {
  128. try {
  129. this.diagramConfigurationService.edit(diagramConfiguration);
  130. } catch (Exception e) {
  131. e.printStackTrace();
  132. log.error(CommonConstants.MSG_ERROR_OPERATE, e);
  133. return Result.error(e.getMessage());
  134. }
  135. return Result.OK(CommonConstants.MSG_SUCCESS_EDIT, null);
  136. }
  137. /**
  138. * 通过id删除
  139. *
  140. * @param id
  141. * @return
  142. */
  143. @AutoLog(value = "图表配置-通过id删除")
  144. @ApiOperation(value = "图表配置-通过id删除", notes = "图表配置-通过id删除")
  145. @PostMapping(value = "/delete")
  146. public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
  147. try {
  148. this.diagramConfigurationService.deleteById(id);
  149. } catch (Exception e) {
  150. e.printStackTrace();
  151. log.error(CommonConstants.MSG_ERROR_OPERATE, e);
  152. return Result.error(e.getMessage());
  153. }
  154. return Result.OK(CommonConstants.MSG_SUCCESS_DELTET, null);
  155. }
  156. /**
  157. * 批量删除
  158. *
  159. * @param ids
  160. * @return
  161. */
  162. @AutoLog(value = "图表配置-批量删除")
  163. @ApiOperation(value = "图表配置-批量删除", notes = "图表配置-批量删除")
  164. @PostMapping(value = "/deleteBatch")
  165. public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
  166. try {
  167. this.diagramConfigurationService.deleteBatch(ids);
  168. } catch (Exception e) {
  169. e.printStackTrace();
  170. log.error(CommonConstants.MSG_ERROR_OPERATE, e);
  171. return Result.error(e.getMessage());
  172. }
  173. return Result.OK(CommonConstants.MSG_SUCCESS_DELTET_BATCH, null);
  174. }
  175. /**
  176. * 通过id查询
  177. *
  178. * @param id
  179. * @return
  180. */
  181. @AutoLog(value = "图表配置-通过id查询")
  182. @ApiOperation(value = "图表配置-通过id查询", notes = "图表配置-通过id查询")
  183. @GetMapping(value = "/queryById")
  184. public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
  185. DiagramConfiguration diagramConfiguration = diagramConfigurationService.getById(id);
  186. if (diagramConfiguration == null) {
  187. return Result.error(CommonConstants.MSG_ERROR_NO_DATA_FOUND + "[ " + id + " ]");
  188. }
  189. return Result.OK(diagramConfiguration);
  190. }
  191. /**
  192. * 导出excel
  193. *
  194. * @param request
  195. * @param diagramConfiguration
  196. */
  197. @RequestMapping(value = "/exportXls")
  198. public ModelAndView exportXls(HttpServletRequest request, DiagramConfiguration diagramConfiguration) {
  199. return super.exportXls(request, diagramConfiguration, DiagramConfiguration.class, "图表配置");
  200. }
  201. /**
  202. * 通过excel导入数据
  203. *
  204. * @param request
  205. * @param response
  206. * @return
  207. */
  208. @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
  209. public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
  210. return super.importExcel(request, response, DiagramConfiguration.class);
  211. }
  212. /**
  213. * 获取图表数据 【注意】当 dataType="sql" 时,遇到 插入、删除、更新(查询数据报错) 【目的】阻止除RUD语句执行,破坏数据
  214. *
  215. * @param code
  216. * @return
  217. */
  218. // @AutoLog(value = "图表配置-获取图表数据")
  219. @ApiOperation(value="图表配置-获取图表数据", notes="图表配置-获取图表数据")
  220. @RequestMapping(value = "/getChartsData", method = RequestMethod.GET)
  221. @Transactional(readOnly = true)
  222. public Result<?> getChartsData(@RequestParam(name = "code", required = true) String code,
  223. @RequestParam(name = "params", required = false) String params) {
  224. // 查询主表信息
  225. QueryWrapper<DiagramConfiguration> diagramConfigurationQueryWrapper = new QueryWrapper<>();
  226. diagramConfigurationQueryWrapper.eq("code", code);
  227. DiagramConfiguration diagramConfiguration = this.diagramConfigurationService
  228. .getOne(diagramConfigurationQueryWrapper);
  229. if (diagramConfiguration == null) {
  230. return Result.error(CommonConstants.MSG_ERROR_NO_DATA_FOUND + "[ " + code + " ]");
  231. }
  232. // 根据sql查询数据
  233. List dataList = Collections.emptyList();
  234. if (CommonConstants.DATA_TYPE_SQL.equals(diagramConfiguration.getDataType())) {
  235. String cgrSql = diagramConfiguration.getCgrSql();
  236. // 向SQL拼装查询条件
  237. cgrSql = this.assemblySql(cgrSql, params);
  238. dataList = this.diagramConfigurationService.selectBySql(cgrSql);
  239. }
  240. // 获取子表信息
  241. QueryWrapper<DiagramFieldConfiguration> diagramFieldConfigurationQueryWrapper = new QueryWrapper<>();
  242. diagramFieldConfigurationQueryWrapper.eq("DIAGRAM_CODE", code);
  243. diagramFieldConfigurationQueryWrapper.orderByAsc("order_num");
  244. List<DiagramFieldConfiguration> diagramFieldConfigurationList = this.diagramFieldConfigurationService
  245. .list(diagramFieldConfigurationQueryWrapper);
  246. Map<String, Expression> expressions = new HashMap<>();
  247. Map<String, String> aggregates = new HashMap<>();
  248. Map<Object,Map<String, Object>> aggregateDataMap = new HashMap<Object,Map<String, Object>>();
  249. String xField = diagramConfiguration.getXaxisField();
  250. String[] groupFields = diagramConfiguration.getGroupField().split(",");
  251. for(DiagramFieldConfiguration dfc : diagramFieldConfigurationList){
  252. if(StringUtils.isNotEmpty(dfc.getFunc())){
  253. String expression = dfc.getFunc();
  254. Expression compiledExp = AviatorEvaluator.compile(expression);
  255. expressions.put(dfc.getFieldName(), compiledExp);
  256. }
  257. if(StringUtils.isNotEmpty(dfc.getAggregateType())){
  258. aggregates.put(dfc.getFieldName(), dfc.getAggregateType());
  259. }
  260. if(ArrayUtils.contains(groupFields, dfc.getFieldName())){
  261. aggregates.put(dfc.getFieldName(), dfc.getAggregateType());
  262. }
  263. }
  264. if(expressions.size()>0 || diagramConfiguration.getAggregate()){
  265. for(Object data : dataList){
  266. if(data instanceof Map){
  267. for(Entry<String, Expression> entry : expressions.entrySet()){
  268. Map<String,Object> env = new HashMap<String,Object>();
  269. env.putAll((Map<String,Object>) data);
  270. ((Map<String,Object>) data).put(entry.getKey(), entry.getValue().execute(env));
  271. }
  272. if(diagramConfiguration.getAggregate()){
  273. Object xValue = ((Map) data).get(xField);
  274. if(aggregateDataMap.get(xValue) == null){
  275. Map<String, Object> aggregateData = new HashMap<>();
  276. aggregateData.put(xField, xValue);
  277. for(Entry<String, String> yField : aggregates.entrySet()){
  278. aggregateData.put(yField.getKey(),BigDecimal.ZERO);
  279. }
  280. aggregateDataMap.put(xValue, aggregateData);
  281. }
  282. Map<String, Object> aggregateData = aggregateDataMap.get(xValue);
  283. for(Entry<String, String> yField : aggregates.entrySet()){
  284. aggregateData.put(yField.getKey(), OnlineUtil.calculation(aggregateData.get(yField.getKey()), ((Map) data).get(yField.getKey()), yField.getValue()));
  285. }
  286. aggregateDataMap.put(xValue, aggregateData);
  287. }
  288. }
  289. }
  290. }
  291. // 处理树形表格数据
  292. if (diagramConfiguration.getGraphType().equals("treeTable")) {
  293. String unfoldFieldName = diagramFieldConfigurationList.get(0).getFieldName();
  294. dataList = this.diagramConfigurationService.handelTreeTableData(dataList, unfoldFieldName, diagramConfiguration.getPid());
  295. }
  296. Map<String,Collection> result = new HashMap<String, Collection>();
  297. result.put("data", dataList);
  298. result.put("aggregate", aggregateDataMap.values());
  299. // 封装数据
  300. ChartsData<Object, DiagramConfiguration, DiagramFieldConfiguration> chartsData = new ChartsData<>();
  301. chartsData.setData(result);
  302. chartsData.setDictOptions(null);
  303. chartsData.setHead(diagramConfiguration);
  304. chartsData.setItems(diagramFieldConfigurationList);
  305. return Result.ok(chartsData);
  306. }
  307. /**
  308. * sql预解析 【注意】遇到 插入、删除、更新(会提示解析失败) 【目的】阻止除RUD语句执行,破坏数据
  309. *
  310. * @param sql
  311. * @return
  312. */
  313. // @AutoLog(value = "图表配置-sql预解析")
  314. @ApiOperation(value="图表配置-sql预解析", notes="图表配置-sql预解析")
  315. @RequestMapping(value = "/parseSql", method = RequestMethod.POST)
  316. @Transactional(readOnly = true)
  317. public Result<?> parseSql(@RequestParam(name = "sql", required = true) String sql) {
  318. Set<String> keys = null;
  319. try {
  320. List<Map<String,String>> result = this.diagramConfigurationService.selectBySql(sql);
  321. if(result == null || result.size() == 0){
  322. log.error(CommonConstants.MSG_ERROR_NO_DATA_FOUND);
  323. return Result.error(CommonConstants.MSG_ERROR_NO_DATA_FOUND);
  324. }else{
  325. Map<String,String> map = result.get(0);
  326. keys = map.keySet();
  327. }
  328. } catch (Exception e) {
  329. e.printStackTrace();
  330. log.error(CommonConstants.MSG_ERROR_PARSING, e);
  331. return Result.error(CommonConstants.MSG_ERROR_PARSING);
  332. }
  333. return Result.OK(CommonConstants.MSG_SUCCESS_PARSING,keys);
  334. }
  335. /**
  336. * 远程code重复校验
  337. *
  338. * @param code
  339. * @return
  340. */
  341. @AutoLog(value = "图表配置-code重复校验")
  342. @ApiOperation(value = "图表配置-code重复校验", notes = "图表配置-code重复校验")
  343. @RequestMapping(value = "/codeCheck", method = RequestMethod.GET)
  344. public Result<?> codeCheck(@RequestParam(name = "code", required = true) String code) {
  345. Result<?> result = this.duplicateCheck(code);
  346. if (result != null) {
  347. return result;
  348. }
  349. return Result.OK();
  350. }
  351. /**
  352. * code重复校验
  353. *
  354. * @param code
  355. * @return
  356. */
  357. private Result<?> duplicateCheck(String code) {
  358. QueryWrapper<DiagramConfiguration> queryWrapper = new QueryWrapper<>();
  359. queryWrapper.eq("code", code);
  360. List<DiagramConfiguration> diagramConfigurationList = this.diagramConfigurationService.list(queryWrapper);
  361. if (diagramConfigurationList != null && !diagramConfigurationList.isEmpty()) {
  362. return Result.error(CommonConstants.MSG_EXIST + "[ " + code + " ]");
  363. }
  364. return null;
  365. }
  366. /**
  367. * 组装SQL,用于图表查询
  368. * @param sql
  369. * @param params
  370. * @return
  371. */
  372. private static String assemblySql(String sql, String params) {
  373. if (org.springframework.util.StringUtils.isEmpty(params)) {
  374. return sql;
  375. } else {
  376. // 拼装sql
  377. StringBuilder sbe = new StringBuilder("select * from (");
  378. sbe.append(sql);
  379. sbe.append(") tt where 1 = 1 ");
  380. JSONArray jsonArray = null;
  381. try {
  382. jsonArray = JSONArray.parseArray(URLDecoder.decode(params, "UTF-8"));
  383. } catch (UnsupportedEncodingException e) {
  384. e.printStackTrace();
  385. }
  386. for (int i = 0; i < jsonArray.size(); i++) {
  387. JSONObject jsonObject = jsonArray.getJSONObject(i);
  388. String fieldName = jsonObject.getString("fieldName");
  389. String fieldType = jsonObject.getString("fieldType");
  390. String searchMode = jsonObject.getString("searchMode");
  391. if (searchMode.equals("single")) {
  392. if (fieldType.equals("String")) {
  393. String value = jsonObject.getString("value");
  394. if (!org.springframework.util.StringUtils.isEmpty(value)) {
  395. sbe.append(" and " + fieldName + " = '" + value + "'");
  396. }
  397. } else {
  398. Integer value = jsonObject.getInteger("value");
  399. if (value != null) {
  400. sbe.append(" and " + fieldName + " = " + value);
  401. }
  402. }
  403. } else {
  404. if (fieldType.equals("String")) {
  405. JSONArray valueArr = jsonObject.getJSONArray("value");
  406. String startValue = valueArr.getString(0);
  407. String endValue = valueArr.getString(1);
  408. if (!org.springframework.util.StringUtils.isEmpty(startValue)) {
  409. sbe.append(" and " + fieldName + " >= '" + startValue + "'" );
  410. }
  411. if (!org.springframework.util.StringUtils.isEmpty(endValue)) {
  412. sbe.append(" and " + fieldName + " <= '" + endValue + "'" );
  413. }
  414. } else {
  415. JSONArray valueArr = jsonObject.getJSONArray("value");
  416. Integer startValue = valueArr.getInteger(0);
  417. Integer endValue = valueArr.getInteger(1);
  418. if (startValue != null) {
  419. sbe.append(" and " + fieldName + " >= " + startValue);
  420. }
  421. if (endValue != null) {
  422. sbe.append(" and " + fieldName + " <= " + endValue);
  423. }
  424. }
  425. }
  426. }
  427. return sbe.toString();
  428. }
  429. }
  430. }