李云瑞 hai 1 ano
pai
achega
51e9bd8462
Modificáronse 49 ficheiros con 1779 adicións e 0 borrados
  1. 12 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/JeecgService.java
  2. 19 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.java
  3. 130 0
      jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/JeecgTenantParser.java
  4. BIN=BIN
      jeecg-boot-base-core/target/classes/org/jeecg/common/system/base/service/JeecgService.class
  5. BIN=BIN
      jeecg-boot-base-core/target/classes/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.class
  6. 255 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java
  7. 245 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JoaDemoController.java
  8. 48 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/entity/JeecgOrderTicket.java
  9. 67 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/entity/JoaDemo.java
  10. 17 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgOrderMainMapper.java
  11. 33 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgOrderTicketMapper.java
  12. 15 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JoaDemoMapper.java
  13. 5 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderMainMapper.xml
  14. 5 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderTicketMapper.xml
  15. 5 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JoaDemoMapper.xml
  16. 162 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgOrderMainServiceImpl.java
  17. 29 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgOrderTicketServiceImpl.java
  18. 19 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JoaDemoServiceImpl.java
  19. 50 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/vo/JeecgOrderMainPage.java
  20. BIN=BIN
      jeecg-module-demo/src/main/resources/static/bigscreen/template2/images/jian.png
  21. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/controller/JoaDemoController.class
  22. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/entity/JeecgOrderTicket.class
  23. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/entity/JoaDemo.class
  24. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JeecgOrderMainMapper.class
  25. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JeecgOrderTicketMapper.class
  26. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JoaDemoMapper.class
  27. 5 0
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderMainMapper.xml
  28. 5 0
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderTicketMapper.xml
  29. 5 0
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JoaDemoMapper.xml
  30. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JeecgOrderMainServiceImpl.class
  31. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JeecgOrderTicketServiceImpl.class
  32. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JoaDemoServiceImpl.class
  33. BIN=BIN
      jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/vo/JeecgOrderMainPage.class
  34. BIN=BIN
      jeecg-module-demo/target/classes/static/bigscreen/template2/images/jian.png
  35. 69 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/jimureport/JimuReportTokenService.java
  36. BIN=BIN
      jeecg-module-system/jeecg-system-biz/target/classes/org/jeecg/config/jimureport/JimuReportTokenService.class
  37. 44 0
      jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java
  38. BIN=BIN
      jeecg-module-system/jeecg-system-start/target/classes/org/jeecg/JeecgSystemApplication.class
  39. 69 0
      jeecg-server-cloud/jeecg-system-cloud-start/src/main/java/org/jeecg/JeecgSystemCloudApplication.java
  40. 49 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-sentinel/src/main/java/com/alibaba/csp/sentinel/dashboard/JeecgSentinelApplication.java
  41. 30 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/client/JeecgTestClient.java
  42. 15 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/client/JeecgTestClientDyn.java
  43. 78 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/controller/JeecgTestFeignController.java
  44. 23 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/factory/JeecgTestClientFactory.java
  45. 25 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/fallback/JeecgTestFallback.java
  46. 89 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-shardingsphere/src/main/java/org/jeecg/modules/test/sharding/controller/JeecgShardingDemoController.java
  47. 72 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/controller/JobApiController.java
  48. 20 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/core/alarm/JobAlarm.java
  49. 65 0
      jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java

+ 12 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/JeecgService.java

@@ -0,0 +1,12 @@
+package org.jeecg.common.system.base.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: Service基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-21 8:13
+ * @Version: 1.0
+ */
+public interface JeecgService<T> extends IService<T> {
+}

+ 19 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.java

@@ -0,0 +1,19 @@
+package org.jeecg.common.system.base.service.impl;
+
+import org.jeecg.common.system.base.entity.JeecgEntity;
+import org.jeecg.common.system.base.service.JeecgService;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: ServiceImpl基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-21 8:13
+ * @Version: 1.0
+ */
+@Slf4j
+public class JeecgServiceImpl<M extends BaseMapper<T>, T extends JeecgEntity> extends ServiceImpl<M, T> implements JeecgService<T> {
+
+}

+ 130 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/JeecgTenantParser.java

@@ -0,0 +1,130 @@
+//package org.jeecg.config.mybatis;
+//
+//import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+//import net.sf.jsqlparser.expression.BinaryExpression;
+//import net.sf.jsqlparser.expression.Expression;
+//import net.sf.jsqlparser.expression.Parenthesis;
+//import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+//import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
+//import net.sf.jsqlparser.expression.operators.relational.*;
+//import net.sf.jsqlparser.schema.Column;
+//import net.sf.jsqlparser.schema.Table;
+//import net.sf.jsqlparser.statement.select.*;
+//
+//import java.util.List;
+//
+///**
+// * 复写租户条件
+// */
+//public class JeecgTenantParser extends TenantSqlParser {
+//
+//    /**
+//     * @param expression
+//     * @param table
+//     * @return
+//     */
+//    protected Expression processTableAlias(Expression expression, Table table) {
+//        String tableAliasName;
+//        if (table.getAlias() == null) {
+//            tableAliasName = table.getName();
+//        } else {
+//            tableAliasName = table.getAlias().getName();
+//        }
+//
+//        // in
+//        if (expression instanceof InExpression) {
+//            InExpression in = (InExpression) expression;
+//            if (in.getLeftExpression() instanceof Column) {
+//                setTableAliasNameForColumn((Column) in.getLeftExpression(), tableAliasName);
+//            }
+//
+//            // 比较操作
+//        } else if (expression instanceof BinaryExpression) {
+//            BinaryExpression compare = (BinaryExpression) expression;
+//            if (compare.getLeftExpression() instanceof Column) {
+//                setTableAliasNameForColumn((Column) compare.getLeftExpression(), tableAliasName);
+//            } else if (compare.getRightExpression() instanceof Column) {
+//                setTableAliasNameForColumn((Column) compare.getRightExpression(), tableAliasName);
+//            }
+//
+//            // between
+//        } else if (expression instanceof Between) {
+//            Between between = (Between) expression;
+//            if (between.getLeftExpression() instanceof Column) {
+//                setTableAliasNameForColumn((Column) between.getLeftExpression(), tableAliasName);
+//            }
+//        }
+//        return expression;
+//    }
+//
+//    private void setTableAliasNameForColumn(Column column, String tableAliasName) {
+//        column.setColumnName(tableAliasName + "." + column.getColumnName());
+//    }
+//
+//    /**
+//     * 默认是按 tenant_id=1 按等于条件追加
+//     *
+//     * @param currentExpression 现有的条件:比如你原来的sql查询条件
+//     * @param table
+//     * @return
+//     */
+//    @Override
+//    protected Expression builderExpression(Expression currentExpression, Table table) {
+//        final Expression tenantExpression = this.getTenantHandler().getTenantId(true);
+//        Expression appendExpression;
+//        if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) {
+//            appendExpression = new EqualsTo();
+//            ((EqualsTo) appendExpression).setLeftExpression(this.getAliasColumn(table));
+//            ((EqualsTo) appendExpression).setRightExpression(tenantExpression);
+//        } else {
+//            appendExpression = processTableAlias(tenantExpression, table);
+//        }
+//        if (currentExpression == null) {
+//            return appendExpression;
+//        }
+//        if (currentExpression instanceof BinaryExpression) {
+//            BinaryExpression binaryExpression = (BinaryExpression) currentExpression;
+//            if (binaryExpression.getLeftExpression() instanceof FromItem) {
+//                processFromItem((FromItem) binaryExpression.getLeftExpression());
+//            }
+//            if (binaryExpression.getRightExpression() instanceof FromItem) {
+//                processFromItem((FromItem) binaryExpression.getRightExpression());
+//            }
+//        } else if (currentExpression instanceof InExpression) {
+//            InExpression inExp = (InExpression) currentExpression;
+//            ItemsList rightItems = inExp.getRightItemsList();
+//            if (rightItems instanceof SubSelect) {
+//                processSelectBody(((SubSelect) rightItems).getSelectBody());
+//            }
+//        }
+//        if (currentExpression instanceof OrExpression) {
+//            return new AndExpression(new Parenthesis(currentExpression), appendExpression);
+//        } else {
+//            return new AndExpression(currentExpression, appendExpression);
+//        }
+//    }
+//
+//    @Override
+//    protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
+//        FromItem fromItem = plainSelect.getFromItem();
+//        if (fromItem instanceof Table) {
+//            Table fromTable = (Table) fromItem;
+//            if (!this.getTenantHandler().doTableFilter(fromTable.getName())) {
+//                plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
+//                if (addColumn) {
+//                    plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn())));
+//                }
+//            }
+//        } else {
+//            processFromItem(fromItem);
+//        }
+//        List<Join> joins = plainSelect.getJoins();
+//        if (joins != null && joins.size() > 0) {
+//            joins.forEach(j -> {
+//                processJoin(j);
+//                processFromItem(j.getRightItem());
+//            });
+//        }
+//    }
+//
+//}

BIN=BIN
jeecg-boot-base-core/target/classes/org/jeecg/common/system/base/service/JeecgService.class


BIN=BIN
jeecg-boot-base-core/target/classes/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.class


+ 255 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java

@@ -0,0 +1,255 @@
+package org.jeecg.modules.demo.test.controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.demo.test.entity.JeecgDemo;
+import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer;
+import org.jeecg.modules.demo.test.entity.JeecgOrderMain;
+import org.jeecg.modules.demo.test.entity.JeecgOrderTicket;
+import org.jeecg.modules.demo.test.service.IJeecgDemoService;
+import org.jeecg.modules.demo.test.service.IJeecgOrderCustomerService;
+import org.jeecg.modules.demo.test.service.IJeecgOrderMainService;
+import org.jeecg.modules.demo.test.service.IJeecgOrderTicketService;
+import org.jeecg.modules.demo.test.vo.JeecgOrderMainPage;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: 一对多示例(JEditableTable行编辑)
+ * @Author: jeecg-boot
+ * @Date:2019-02-15
+ * @Version: V2.0
+ */
+@RestController
+@RequestMapping("/test/jeecgOrderMain")
+@Slf4j
+public class JeecgOrderMainController extends JeecgController<JeecgOrderMain, IJeecgOrderMainService> {
+
+    @Autowired
+    private IJeecgOrderMainService jeecgOrderMainService;
+    @Autowired
+    private IJeecgOrderCustomerService jeecgOrderCustomerService;
+    @Autowired
+    private IJeecgOrderTicketService jeecgOrderTicketService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param jeecgOrderMain
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @GetMapping(value = "/list")
+    public Result<?> queryPageList(JeecgOrderMain jeecgOrderMain, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
+        QueryWrapper<JeecgOrderMain> queryWrapper = QueryGenerator.initQueryWrapper(jeecgOrderMain, req.getParameterMap());
+        Page<JeecgOrderMain> page = new Page<JeecgOrderMain>(pageNo, pageSize);
+        IPage<JeecgOrderMain> pageList = jeecgOrderMainService.page(page, queryWrapper);
+        return Result.ok(pageList);
+    }
+
+    /**
+     * 添加
+     *
+     * @param jeecgOrderMainPage
+     * @return
+     */
+    @PostMapping(value = "/add")
+    public Result<?> add(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
+        JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
+        BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);
+        jeecgOrderMainService.saveMain(jeecgOrderMain, jeecgOrderMainPage.getJeecgOrderCustomerList(), jeecgOrderMainPage.getJeecgOrderTicketList());
+        return Result.ok("添加成功!");
+    }
+
+    /**
+     * 编辑
+     *
+     * @param jeecgOrderMainPage
+     * @return
+     */
+    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
+    public Result<?> eidt(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
+        JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
+        BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);
+        jeecgOrderMainService.updateCopyMain(jeecgOrderMain, jeecgOrderMainPage.getJeecgOrderCustomerList(), jeecgOrderMainPage.getJeecgOrderTicketList());
+        return Result.ok("编辑成功!");
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        jeecgOrderMainService.delMain(id);
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        this.jeecgOrderMainService.delBatchMain(Arrays.asList(ids.split(",")));
+        return Result.ok("批量删除成功!");
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/queryById")
+    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
+        JeecgOrderMain jeecgOrderMain = jeecgOrderMainService.getById(id);
+        return Result.ok(jeecgOrderMain);
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/queryOrderCustomerListByMainId")
+    public Result<?> queryOrderCustomerListByMainId(@RequestParam(name = "id", required = true) String id) {
+        List<JeecgOrderCustomer> jeecgOrderCustomerList = jeecgOrderCustomerService.selectCustomersByMainId(id);
+        return Result.ok(jeecgOrderCustomerList);
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/queryOrderTicketListByMainId")
+    public Result<?> queryOrderTicketListByMainId(@RequestParam(name = "id", required = true) String id) {
+        List<JeecgOrderTicket> jeecgOrderTicketList = jeecgOrderTicketService.selectTicketsByMainId(id);
+        return Result.ok(jeecgOrderTicketList);
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, JeecgOrderMain jeecgOrderMain) {
+        // Step.1 组装查询条件
+        QueryWrapper<JeecgOrderMain> queryWrapper = QueryGenerator.initQueryWrapper(jeecgOrderMain, request.getParameterMap());
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        //获取当前用户
+        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+
+        List<JeecgOrderMainPage> pageList = new ArrayList<JeecgOrderMainPage>();
+
+        List<JeecgOrderMain> jeecgOrderMainList = jeecgOrderMainService.list(queryWrapper);
+        for (JeecgOrderMain orderMain : jeecgOrderMainList) {
+            JeecgOrderMainPage vo = new JeecgOrderMainPage();
+            BeanUtils.copyProperties(orderMain, vo);
+            // 查询机票
+            List<JeecgOrderTicket> jeecgOrderTicketList = jeecgOrderTicketService.selectTicketsByMainId(orderMain.getId());
+            vo.setJeecgOrderTicketList(jeecgOrderTicketList);
+            // 查询客户
+            List<JeecgOrderCustomer> jeecgOrderCustomerList = jeecgOrderCustomerService.selectCustomersByMainId(orderMain.getId());
+            vo.setJeecgOrderCustomerList(jeecgOrderCustomerList);
+            pageList.add(vo);
+        }
+
+        // 导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "一对多订单示例");
+        // 注解对象Class
+        mv.addObject(NormalExcelConstants.CLASS, JeecgOrderMainPage.class);
+        // 自定义表格参数
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("自定义导出Excel内容标题", "导出人:" + sysUser.getRealname(), "自定义Sheet名字"));
+        // 导出数据列表
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            // 获取上传文件对象
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(2);
+            params.setNeedSave(true);
+            try {
+                List<JeecgOrderMainPage> list = ExcelImportUtil.importExcel(file.getInputStream(), JeecgOrderMainPage.class, params);
+                for (JeecgOrderMainPage page : list) {
+                    JeecgOrderMain po = new JeecgOrderMain();
+                    BeanUtils.copyProperties(page, po);
+                    jeecgOrderMainService.saveMain(po, page.getJeecgOrderCustomerList(), page.getJeecgOrderTicketList());
+                }
+                return Result.ok("文件导入成功!");
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.error("文件导入失败!");
+    }
+
+}

+ 245 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JoaDemoController.java

@@ -0,0 +1,245 @@
+package org.jeecg.modules.demo.test.controller;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.demo.test.entity.JoaDemo;
+import org.jeecg.modules.demo.test.service.IJoaDemoService;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import lombok.extern.slf4j.Slf4j;
+
+ /**
+ * @Description: 流程测试
+ * @Author: jeecg-boot
+ * @Date:   2019-05-14
+ * @Version: V1.0
+ */
+@RestController
+@RequestMapping("/test/joaDemo")
+@Slf4j
+public class JoaDemoController {
+	@Autowired
+	private IJoaDemoService joaDemoService;
+	
+	/**
+	  * 分页列表查询
+	 * @param joaDemo
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@GetMapping(value = "/list")
+	public Result<IPage<JoaDemo>> queryPageList(JoaDemo joaDemo,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<JoaDemo>> result = new Result<IPage<JoaDemo>>();
+		QueryWrapper<JoaDemo> queryWrapper = QueryGenerator.initQueryWrapper(joaDemo, req.getParameterMap());
+		Page<JoaDemo> page = new Page<JoaDemo>(pageNo, pageSize);
+		IPage<JoaDemo> pageList = joaDemoService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param joaDemo
+	 * @return
+	 */
+	@PostMapping(value = "/add")
+	public Result<JoaDemo> add(@RequestBody JoaDemo joaDemo) {
+		Result<JoaDemo> result = new Result<JoaDemo>();
+		try {
+			joaDemoService.save(joaDemo);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param joaDemo
+	 * @return
+	 */
+	@PutMapping(value = "/edit")
+	public Result<JoaDemo> edit(@RequestBody JoaDemo joaDemo) {
+		Result<JoaDemo> result = new Result<JoaDemo>();
+		JoaDemo joaDemoEntity = joaDemoService.getById(joaDemo.getId());
+		if(joaDemoEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = joaDemoService.updateById(joaDemo);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@DeleteMapping(value = "/delete")
+	public Result<JoaDemo> delete(@RequestParam(name="id",required=true) String id) {
+		Result<JoaDemo> result = new Result<JoaDemo>();
+		JoaDemo joaDemo = joaDemoService.getById(id);
+		if(joaDemo==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = joaDemoService.removeById(id);
+			if(ok) {
+				result.success("删除成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<JoaDemo> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<JoaDemo> result = new Result<JoaDemo>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.joaDemoService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@GetMapping(value = "/queryById")
+	public Result<JoaDemo> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<JoaDemo> result = new Result<JoaDemo>();
+		JoaDemo joaDemo = joaDemoService.getById(id);
+		if(joaDemo==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(joaDemo);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<JoaDemo> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              JoaDemo joaDemo = JSON.parseObject(deString, JoaDemo.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(joaDemo, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<JoaDemo> pageList = joaDemoService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "流程测试列表");
+      mv.addObject(NormalExcelConstants.CLASS, JoaDemo.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("流程测试列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          // 获取上传文件对象
+          MultipartFile file = entity.getValue();
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<JoaDemo> listJoaDemos = ExcelImportUtil.importExcel(file.getInputStream(), JoaDemo.class, params);
+              for (JoaDemo joaDemoExcel : listJoaDemos) {
+                  joaDemoService.save(joaDemoExcel);
+              }
+              return Result.ok("文件导入成功!数据行数:" + listJoaDemos.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 48 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/entity/JeecgOrderTicket.java

@@ -0,0 +1,48 @@
+package org.jeecg.modules.demo.test.entity;
+
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * @Description: 订单机票
+ * @Author: jeecg-boot
+ * @Date:  2019-02-15
+ * @Version: V1.0
+ */
+@Data
+@TableName("jeecg_order_ticket")
+public class JeecgOrderTicket implements Serializable {
+    private static final long serialVersionUID = 1L;
+    
+	/**主键*/
+    @TableId(type = IdType.ASSIGN_ID)
+	private java.lang.String id;
+	/**航班号*/
+	@Excel(name="航班号",width=15)
+	private java.lang.String ticketCode;
+	/**航班时间*/
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+	@Excel(name="航班时间",width=15,format = "yyyy-MM-dd")
+	private java.util.Date tickectDate;
+	/**外键*/
+	private java.lang.String orderId;
+	/**创建人*/
+	private java.lang.String createBy;
+	/**创建时间*/
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+	private java.util.Date createTime;
+	/**修改人*/
+	private java.lang.String updateBy;
+	/**修改时间*/
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+	private java.util.Date updateTime;
+}

+ 67 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/entity/JoaDemo.java

@@ -0,0 +1,67 @@
+package org.jeecg.modules.demo.test.entity;
+
+import java.io.Serializable;
+
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import lombok.Data;
+
+/**
+ * @Description: 流程测试
+ * @Author: jeecg-boot
+ * @Date:   2019-05-14
+ * @Version: V1.0
+ */
+@Data
+@TableName("joa_demo")
+public class JoaDemo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    
+	/**ID*/
+	@TableId(type = IdType.ASSIGN_ID)
+	private java.lang.String id;
+	/**请假人*/
+	@Excel(name = "请假人", width = 15)
+	private java.lang.String name;
+	/**请假天数*/
+	@Excel(name = "请假天数", width = 15)
+	private java.lang.Integer days;
+	/**开始时间*/
+	@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+	private java.util.Date beginDate;
+	/**请假结束时间*/
+	@Excel(name = "请假结束时间", width = 20, format = "yyyy-MM-dd")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+	private java.util.Date endDate;
+	/**请假原因*/
+	@Excel(name = "请假原因", width = 15)
+	private java.lang.String reason;
+	/**流程状态*/
+	@Excel(name = "流程状态", width = 15)
+	private java.lang.String bpmStatus;
+	/**创建人id*/
+	@Excel(name = "创建人id", width = 15)
+	private java.lang.String createBy;
+	/**创建时间*/
+	@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+	private java.util.Date createTime;
+	/**修改时间*/
+	@Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+	private java.util.Date updateTime;
+	/**修改人id*/
+	@Excel(name = "修改人id", width = 15)
+	private java.lang.String updateBy;
+}

+ 17 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgOrderMainMapper.java

@@ -0,0 +1,17 @@
+package org.jeecg.modules.demo.test.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.demo.test.entity.JeecgOrderMain;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 订单
+ * @Author: jeecg-boot
+ * @Date:  2019-02-15
+ * @Version: V1.0
+ */
+public interface JeecgOrderMainMapper extends BaseMapper<JeecgOrderMain> {
+
+}

+ 33 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgOrderTicketMapper.java

@@ -0,0 +1,33 @@
+package org.jeecg.modules.demo.test.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.demo.test.entity.JeecgOrderTicket;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 订单机票
+ * @Author: jeecg-boot
+ * @Date:  2019-02-15
+ * @Version: V1.0
+ */
+public interface JeecgOrderTicketMapper extends BaseMapper<JeecgOrderTicket> {
+
+	/**
+	 *  通过主表外键批量删除客户
+	 * @param mainId
+	 * @return
+	 */
+    @Delete("DELETE FROM JEECG_ORDER_TICKET WHERE ORDER_ID = #{mainId}")
+	public boolean deleteTicketsByMainId(String mainId);
+
+    /**
+     * 通过主表订单外键查询订单机票
+     * @param mainId 订单id
+     * @return 返回订单机票集合
+     */
+    @Select("SELECT * FROM JEECG_ORDER_TICKET WHERE ORDER_ID = #{mainId}")
+	public List<JeecgOrderTicket> selectTicketsByMainId(String mainId);
+}

+ 15 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JoaDemoMapper.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.demo.test.mapper;
+
+import org.jeecg.modules.demo.test.entity.JoaDemo;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 流程测试
+ * @Author: jeecg-boot
+ * @Date:   2019-05-14
+ * @Version: V1.0
+ */
+public interface JoaDemoMapper extends BaseMapper<JoaDemo> {
+
+}

+ 5 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderMainMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JeecgOrderMainMapper">
+
+</mapper>

+ 5 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderTicketMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JeecgOrderTicketMapper">
+
+</mapper>

+ 5 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JoaDemoMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JoaDemoMapper">
+
+</mapper>

+ 162 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgOrderMainServiceImpl.java

@@ -0,0 +1,162 @@
+package org.jeecg.modules.demo.test.service.impl;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer;
+import org.jeecg.modules.demo.test.entity.JeecgOrderMain;
+import org.jeecg.modules.demo.test.entity.JeecgOrderTicket;
+import org.jeecg.modules.demo.test.mapper.JeecgOrderCustomerMapper;
+import org.jeecg.modules.demo.test.mapper.JeecgOrderMainMapper;
+import org.jeecg.modules.demo.test.mapper.JeecgOrderTicketMapper;
+import org.jeecg.modules.demo.test.service.IJeecgOrderMainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 订单
+ * @Author: jeecg-boot
+ * @Date:  2019-02-15
+ * @Version: V1.0
+ */
+@Service
+public class JeecgOrderMainServiceImpl extends ServiceImpl<JeecgOrderMainMapper, JeecgOrderMain> implements IJeecgOrderMainService {
+
+    @Autowired
+    private JeecgOrderMainMapper jeecgOrderMainMapper;
+    @Autowired
+    private JeecgOrderCustomerMapper jeecgOrderCustomerMapper;
+    @Autowired
+    private JeecgOrderTicketMapper jeecgOrderTicketMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void saveMain(JeecgOrderMain jeecgOrderMain, List<JeecgOrderCustomer> jeecgOrderCustomerList, List<JeecgOrderTicket> jeecgOrderTicketList) {
+        jeecgOrderMainMapper.insert(jeecgOrderMain);
+        if (jeecgOrderCustomerList != null) {
+            for (JeecgOrderCustomer entity : jeecgOrderCustomerList) {
+                entity.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderCustomerMapper.insert(entity);
+            }
+        }
+        if (jeecgOrderTicketList != null) {
+            for (JeecgOrderTicket entity : jeecgOrderTicketList) {
+                entity.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderTicketMapper.insert(entity);
+            }
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateMain(JeecgOrderMain jeecgOrderMain, List<JeecgOrderCustomer> jeecgOrderCustomerList, List<JeecgOrderTicket> jeecgOrderTicketList) {
+        jeecgOrderMainMapper.updateById(jeecgOrderMain);
+
+        //1.先删除子表数据
+        jeecgOrderTicketMapper.deleteTicketsByMainId(jeecgOrderMain.getId());
+        jeecgOrderCustomerMapper.deleteCustomersByMainId(jeecgOrderMain.getId());
+
+        //2.子表数据重新插入
+        if (jeecgOrderCustomerList != null) {
+            for (JeecgOrderCustomer entity : jeecgOrderCustomerList) {
+                entity.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderCustomerMapper.insert(entity);
+            }
+        }
+        if (jeecgOrderTicketList != null) {
+            for (JeecgOrderTicket entity : jeecgOrderTicketList) {
+                entity.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderTicketMapper.insert(entity);
+            }
+        }
+    }
+
+    /**
+     * 一对多维护逻辑改造  LOWCOD-315
+     * @param jeecgOrderMain
+     * @param jeecgOrderCustomerList
+     * @param jeecgOrderTicketList
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateCopyMain(JeecgOrderMain jeecgOrderMain, List<JeecgOrderCustomer> jeecgOrderCustomerList, List<JeecgOrderTicket> jeecgOrderTicketList) {
+        jeecgOrderMainMapper.updateById(jeecgOrderMain);
+
+        // 循环前台传过来的数据
+        for (JeecgOrderTicket ticket:jeecgOrderTicketList){
+            // 先查询子表数据库
+            JeecgOrderTicket orderTicket = jeecgOrderTicketMapper.selectById(ticket.getId());
+            if(orderTicket == null){
+                // 当传过来的id数据库不存在时,说明数据库没有,走新增逻辑
+                ticket.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderTicketMapper.insert(ticket);
+                break;
+            }
+            if(orderTicket.getId().equals(ticket.getId())){
+                // 传过来的id和数据库id一至时,说明数据库存在该数据,走更新逻辑
+                jeecgOrderTicketMapper.updateById(ticket);
+            }
+        }
+        for (JeecgOrderCustomer customer:jeecgOrderCustomerList){
+            // 先查询子表数据库
+            JeecgOrderCustomer customers = jeecgOrderCustomerMapper.selectById(customer.getId());
+            if(customers == null){
+                // 当传过来的id数据库不存在时,说明数据库没有,走新增逻辑
+                customer.setOrderId(jeecgOrderMain.getId());
+                jeecgOrderCustomerMapper.insert(customer);
+                break;
+            }
+            if(customers.getId().equals(customer.getId())){
+                //TODO 传过来的id和数据库id一至时,说明数据库存在该数据,走更新逻辑
+                jeecgOrderCustomerMapper.updateById(customer);
+            }
+        }
+        // 当跟新和删除之后取差集, 当传过来的id不存在,而数据库存在时,说明已删除,走删除逻辑
+        List<JeecgOrderTicket> jeecgOrderTickets = jeecgOrderTicketMapper.selectTicketsByMainId(jeecgOrderMain.getId());
+        List<JeecgOrderTicket> collect = jeecgOrderTickets.stream()
+                .filter(item -> !jeecgOrderTicketList.stream()
+                .map(e -> e.getId())
+                .collect(Collectors.toList())
+                .contains(item.getId()))
+                .collect(Collectors.toList());
+        // for循环删除id
+        for (JeecgOrderTicket ticket:collect){
+            jeecgOrderTicketMapper.deleteById(ticket.getId());
+        }
+
+        List<JeecgOrderCustomer> jeecgOrderCustomers = jeecgOrderCustomerMapper.selectCustomersByMainId(jeecgOrderMain.getId());
+        List<JeecgOrderCustomer> customersCollect = jeecgOrderCustomers.stream()
+                .filter(item -> !jeecgOrderCustomerList.stream()
+                        .map(e -> e.getId())
+                        .collect(Collectors.toList())
+                        .contains(item.getId()))
+                .collect(Collectors.toList());
+        //TODO for循环删除id
+        for (JeecgOrderCustomer c:customersCollect){
+            jeecgOrderCustomerMapper.deleteById(c.getId());
+        }
+    }
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void delMain(String id) {
+		jeecgOrderMainMapper.deleteById(id);
+		jeecgOrderTicketMapper.deleteTicketsByMainId(id);
+		jeecgOrderCustomerMapper.deleteCustomersByMainId(id);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void delBatchMain(Collection<? extends Serializable> idList) {
+		for(Serializable id:idList) {
+			jeecgOrderMainMapper.deleteById(id);
+			jeecgOrderTicketMapper.deleteTicketsByMainId(id.toString());
+			jeecgOrderCustomerMapper.deleteCustomersByMainId(id.toString());
+		}
+	}
+
+}

+ 29 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgOrderTicketServiceImpl.java

@@ -0,0 +1,29 @@
+package org.jeecg.modules.demo.test.service.impl;
+
+import java.util.List;
+
+import org.jeecg.modules.demo.test.entity.JeecgOrderTicket;
+import org.jeecg.modules.demo.test.mapper.JeecgOrderTicketMapper;
+import org.jeecg.modules.demo.test.service.IJeecgOrderTicketService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 订单机票
+ * @Author: jeecg-boot
+ * @Date:  2019-02-15
+ * @Version: V1.0
+ */
+@Service
+public class JeecgOrderTicketServiceImpl extends ServiceImpl<JeecgOrderTicketMapper, JeecgOrderTicket> implements IJeecgOrderTicketService {
+	@Autowired
+	private JeecgOrderTicketMapper jeecgOrderTicketMapper;
+	
+	@Override
+	public List<JeecgOrderTicket> selectTicketsByMainId(String mainId) {
+		return jeecgOrderTicketMapper.selectTicketsByMainId(mainId);
+	}
+
+}

+ 19 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JoaDemoServiceImpl.java

@@ -0,0 +1,19 @@
+package org.jeecg.modules.demo.test.service.impl;
+
+import org.jeecg.modules.demo.test.entity.JoaDemo;
+import org.jeecg.modules.demo.test.mapper.JoaDemoMapper;
+import org.jeecg.modules.demo.test.service.IJoaDemoService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 流程测试
+ * @Author: jeecg-boot
+ * @Date:   2019-05-14
+ * @Version: V1.0
+ */
+@Service
+public class JoaDemoServiceImpl extends ServiceImpl<JoaDemoMapper, JoaDemo> implements IJoaDemoService {
+
+}

+ 50 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/vo/JeecgOrderMainPage.java

@@ -0,0 +1,50 @@
+package org.jeecg.modules.demo.test.vo;
+
+import java.util.List;
+
+import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer;
+import org.jeecg.modules.demo.test.entity.JeecgOrderTicket;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.jeecgframework.poi.excel.annotation.ExcelCollection;
+
+import lombok.Data;
+
+/**
+ * @Description: 一对多示例
+ * @author: jeecg-boot
+ */
+@Data
+public class JeecgOrderMainPage {
+	
+	/**主键*/
+	private java.lang.String id;
+	/**订单号*/
+	@Excel(name="订单号",width=15)
+	private java.lang.String orderCode;
+	/**订单类型*/
+	private java.lang.String ctype;
+	/**订单日期*/
+	@Excel(name="订单日期",width=15,format = "yyyy-MM-dd")
+	private java.util.Date orderDate;
+	/**订单金额*/
+	@Excel(name="订单金额",width=15)
+	private java.lang.Double orderMoney;
+	/**订单备注*/
+	private java.lang.String content;
+	/**创建人*/
+	private java.lang.String createBy;
+	/**创建时间*/
+	private java.util.Date createTime;
+	/**修改人*/
+	private java.lang.String updateBy;
+	/**修改时间*/
+	private java.util.Date updateTime;
+	
+	@ExcelCollection(name="客户")
+	private List<JeecgOrderCustomer> jeecgOrderCustomerList;
+	@ExcelCollection(name="机票")
+	private List<JeecgOrderTicket> jeecgOrderTicketList;
+
+	private String bpmStatus;
+	
+}

BIN=BIN
jeecg-module-demo/src/main/resources/static/bigscreen/template2/images/jian.png


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/controller/JoaDemoController.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/entity/JeecgOrderTicket.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/entity/JoaDemo.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JeecgOrderMainMapper.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JeecgOrderTicketMapper.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/JoaDemoMapper.class


+ 5 - 0
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderMainMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JeecgOrderMainMapper">
+
+</mapper>

+ 5 - 0
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JeecgOrderTicketMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JeecgOrderTicketMapper">
+
+</mapper>

+ 5 - 0
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/mapper/xml/JoaDemoMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.demo.test.mapper.JoaDemoMapper">
+
+</mapper>

BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JeecgOrderMainServiceImpl.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JeecgOrderTicketServiceImpl.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/service/impl/JoaDemoServiceImpl.class


BIN=BIN
jeecg-module-demo/target/classes/org/jeecg/modules/demo/test/vo/JeecgOrderMainPage.class


BIN=BIN
jeecg-module-demo/target/classes/static/bigscreen/template2/images/jian.png


+ 69 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/jimureport/JimuReportTokenService.java

@@ -0,0 +1,69 @@
+package org.jeecg.config.jimureport;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.jeecg.common.util.RedisUtil;
+import org.jeecg.common.util.TokenUtils;
+import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
+import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
+ *  * 1.自定义获取登录token
+ *  * 2.自定义获取登录用户
+ * @author: jeecg-boot
+ */
+
+
+@Slf4j
+@Component
+public class JimuReportTokenService implements JmReportTokenServiceI {
+    @Autowired
+    private SysBaseApiImpl sysBaseApi;
+    @Autowired
+    @Lazy
+    private RedisUtil redisUtil;
+
+    @Override
+    public String getToken(HttpServletRequest request) {
+        return TokenUtils.getTokenByRequest(request);
+    }
+
+    @Override
+    public String getUsername(String token) {
+        return JwtUtil.getUsername(token);
+    }
+
+    @Override
+    public Boolean verifyToken(String token) {
+        return TokenUtils.verifyToken(token, sysBaseApi, redisUtil);
+    }
+
+    @Override
+    public Map<String, Object> getUserInfo(String token) {
+        Map<String, Object> map = new HashMap(5);
+        String username = JwtUtil.getUsername(token);
+        //此处通过token只能拿到一个信息 用户账号  后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
+        SysUserCacheInfo userInfo = null;
+        try {
+            userInfo = sysBaseApi.getCacheUser(username);
+        } catch (Exception e) {
+            log.error("获取用户信息异常:"+ e.getMessage());
+            return map;
+        }
+        //设置账号名
+        map.put(SYS_USER_CODE, userInfo.getSysUserCode());
+        //设置部门编码
+        map.put(SYS_ORG_CODE, userInfo.getSysOrgCode());
+        // 将所有信息存放至map 解析sql/api会根据map的键值解析
+        return map;
+    }
+}

BIN=BIN
jeecg-module-system/jeecg-system-biz/target/classes/org/jeecg/config/jimureport/JimuReportTokenService.class


+ 44 - 0
jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java

@@ -0,0 +1,44 @@
+package org.jeecg;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.oConvertUtils;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+* 单体启动类
+* 报错提醒: 未集成mongo报错,可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
+*/
+@Slf4j
+@SpringBootApplication
+//@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
+public class JeecgSystemApplication extends SpringBootServletInitializer {
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(JeecgSystemApplication.class);
+    }
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(JeecgSystemApplication.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
+        log.info("\n----------------------------------------------------------\n\t" +
+                "Application Jeecg-Boot is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + path + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + path + "/\n\t" +
+                "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
+                "----------------------------------------------------------");
+
+    }
+
+}

BIN=BIN
jeecg-module-system/jeecg-system-start/target/classes/org/jeecg/JeecgSystemApplication.class


+ 69 - 0
jeecg-server-cloud/jeecg-system-cloud-start/src/main/java/org/jeecg/JeecgSystemCloudApplication.java

@@ -0,0 +1,69 @@
+package org.jeecg;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.base.BaseMap;
+import org.jeecg.common.constant.GlobalConstants;
+import org.jeecg.common.util.oConvertUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 微服务启动类(采用此类启动项目为微服务模式)
+ *  注意: 需要先在naocs里面创建配置文件,参考文档 http://doc.jeecg.com/2704725
+ * @author zyf
+ * @date: 2022/4/21 10:55
+ */
+@Slf4j
+@SpringBootApplication
+@EnableFeignClients(basePackages = {"org.jeecg"})
+@EnableScheduling
+public class JeecgSystemCloudApplication extends SpringBootServletInitializer implements CommandLineRunner {
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(JeecgSystemCloudApplication.class);
+    }
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(JeecgSystemCloudApplication.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
+        log.info("\n----------------------------------------------------------\n\t" +
+                "Application Jeecg-Boot is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + path + "/doc.html\n" +
+                "External: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
+                "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
+                "----------------------------------------------------------");
+
+    }
+
+    /**
+     * 启动的时候,触发下gateway网关刷新
+     *
+     * 解决: 先启动gateway后启动服务,Swagger接口文档访问不通的问题
+     * @param args
+     */
+    @Override
+    public void run(String... args) {
+        BaseMap params = new BaseMap();
+        params.put(GlobalConstants.HANDLER_NAME, GlobalConstants.LODER_ROUDER_HANDLER);
+        //刷新网关
+        redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params);
+    }
+}

+ 49 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-sentinel/src/main/java/com/alibaba/csp/sentinel/dashboard/JeecgSentinelApplication.java

@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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 com.alibaba.csp.sentinel.dashboard;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+import com.alibaba.csp.sentinel.init.InitExecutor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Sentinel dashboard application.
+ *
+ * @author Carpenter Lee
+ */
+@SpringBootApplication
+@Slf4j
+public class JeecgSentinelApplication {
+
+    public static void main(String[] args) {
+        System.setProperty("csp.sentinel.app.type", "1");
+        triggerSentinelInit();
+        ConfigurableApplicationContext application = SpringApplication.run(JeecgSentinelApplication.class, args);
+        Environment env = application.getEnvironment();
+        String port = env.getProperty("server.port");
+        log.info("\n----------------------------------------------------------\n\t" +
+                "Application SentinelDashboard is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port  + "/\n\t" +
+                "----------------------------------------------------------");
+    }
+
+    private static void triggerSentinelInit() {
+        new Thread(() -> InitExecutor.doInit()).start();
+    }
+}

+ 30 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/client/JeecgTestClient.java

@@ -0,0 +1,30 @@
+package org.jeecg.modules.test.feign.client;
+
+import org.jeecg.common.api.vo.Result;
+
+import org.jeecg.common.constant.ServiceNameConstants;
+import org.jeecg.config.FeignConfig;
+import org.jeecg.modules.test.constant.CloudConstant;
+import org.jeecg.modules.test.feign.factory.JeecgTestClientFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 常规feign接口定义
+ * @author: zyf
+ * @date: 2022/04/21
+ */
+@FeignClient(value = ServiceNameConstants.SERVICE_DEMO, configuration = FeignConfig.class,fallbackFactory = JeecgTestClientFactory.class)
+@Component
+public interface JeecgTestClient {
+
+    /**
+     * feign测试方法
+     * @param name
+     * @return
+     */
+    @GetMapping(value = "/test/getMessage")
+    String getMessage(@RequestParam(value = "name",required = false) String name);
+}

+ 15 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/client/JeecgTestClientDyn.java

@@ -0,0 +1,15 @@
+//package org.jeecg.modules.test.feign.client;
+//
+//import org.jeecg.common.api.vo.Result;
+//import org.springframework.web.bind.annotation.GetMapping;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestParam;
+//
+///**
+// * 动态feign接口定义
+// */
+//public interface JeecgTestClientDyn {
+//
+//    @GetMapping(value = "/test/getMessage")
+//    Result<String> getMessage(@RequestParam(value = "name",required = false) String name);
+//}

+ 78 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/controller/JeecgTestFeignController.java

@@ -0,0 +1,78 @@
+package org.jeecg.modules.test.feign.controller;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.test.feign.client.JeecgTestClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.alibaba.csp.sentinel.annotation.SentinelResource;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 微服务单元测试
+ * @author: zyf
+ * @date: 2022/04/21
+ */
+@Slf4j
+@RestController
+@RequestMapping("/sys/test")
+@Api(tags = "【微服务】单元测试")
+public class JeecgTestFeignController {
+
+    @Autowired
+    private JeecgTestClient jeecgTestClient;
+
+    /**
+     * 熔断: fallbackFactory优先于 @SentinelResource
+     *
+     * @param name
+     * @return
+     */
+    @GetMapping("/getMessage")
+    @ApiOperation(value = "测试feign调用demo服务1", notes = "测试feign @SentinelResource熔断写法 | 测试熔断关闭jeecg-demo服务")
+    @SentinelResource(value = "test_more_getMessage", fallback = "getDefaultUser")
+    public Result<String> getMessage(@RequestParam(value = "name", required = false) String name) {
+        log.info("---------Feign fallbackFactory优先级高于@SentinelResource-----------------");
+        String resultMsg = jeecgTestClient.getMessage(" I am jeecg-system 服务节点,呼叫 jeecg-demo!");
+        return Result.OK(null, resultMsg);
+    }
+
+    /**
+     * 测试方法:关闭demo服务,访问请求 http://127.0.0.1:9999/sys/test/getMessage
+     *
+     * @param name
+     * @return
+     */
+    @GetMapping("/getMessage2")
+    @ApiOperation(value = "测试feign调用demo服务2", notes = "测试feign fallbackFactory熔断写法 | 测试熔断关闭jeecg-demo服务")
+    public Result<String> getMessage2(@RequestParam(value = "name", required = false) String name) {
+        log.info("---------测试 Feign fallbackFactory-----------------");
+        String resultMsg = jeecgTestClient.getMessage(" I am jeecg-system 服务节点,呼叫 jeecg-demo!");
+        return Result.OK(null, resultMsg);
+    }
+
+
+    @GetMapping("/fallback")
+    @ApiOperation(value = "测试熔断", notes = "测试熔断")
+    @SentinelResource(value = "test_more_fallback", fallback = "getDefaultUser")
+    public Result<Object> test(@RequestParam(value = "name", required = false) String name) {
+        if (StringUtils.isEmpty(name)) {
+            throw new IllegalArgumentException("name param is empty");
+        }
+        return Result.OK();
+    }
+
+    /**
+     * 熔断,默认回调函数
+     *
+     * @param name
+     * @return
+     */
+    public Result<Object> getDefaultUser(String name) {
+        log.info("熔断,默认回调函数");
+        return Result.error(null, "访问超时, 自定义 @SentinelResource Fallback");
+    }
+}

+ 23 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/factory/JeecgTestClientFactory.java

@@ -0,0 +1,23 @@
+package org.jeecg.modules.test.feign.factory;
+
+
+
+
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.jeecg.modules.test.feign.client.JeecgTestClient;
+import org.jeecg.modules.test.feign.fallback.JeecgTestFallback;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author qinfeng
+ */
+@Component
+public class JeecgTestClientFactory implements FallbackFactory<JeecgTestClient> {
+
+    @Override
+    public JeecgTestClient create(Throwable throwable) {
+        JeecgTestFallback fallback = new JeecgTestFallback();
+        fallback.setCause(throwable);
+        return fallback;
+    }
+}

+ 25 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-more/src/main/java/org/jeecg/modules/test/feign/fallback/JeecgTestFallback.java

@@ -0,0 +1,25 @@
+package org.jeecg.modules.test.feign.fallback;
+
+import org.jeecg.common.api.vo.Result;
+
+import lombok.Setter;
+import org.jeecg.modules.test.feign.client.JeecgTestClient;
+
+
+/**
+* 接口fallback实现
+* 
+* @author: scott
+* @date: 2022/4/11 19:41
+*/
+public class JeecgTestFallback implements JeecgTestClient {
+
+    @Setter
+    private Throwable cause;
+
+
+    @Override
+    public String getMessage(String name) {
+        return "访问超时, 自定义FallbackFactory";
+    }
+}

+ 89 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-test/jeecg-cloud-test-shardingsphere/src/main/java/org/jeecg/modules/test/sharding/controller/JeecgShardingDemoController.java

@@ -0,0 +1,89 @@
+package org.jeecg.modules.test.sharding.controller;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.modules.test.sharding.entity.ShardingSysLog;
+import org.jeecg.modules.test.sharding.service.IShardingSysLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: 分库分表测试
+ * @author: zyf
+ * @date: 2022/01/24
+ * @version: V1.0
+ */
+@Slf4j
+@Api(tags = "分库分表测试")
+@RestController
+@RequestMapping("/sharding")
+public class JeecgShardingDemoController extends JeecgController<ShardingSysLog, IShardingSysLogService> {
+    @Autowired
+    private IShardingSysLogService shardingSysLogService;
+
+    /**
+     * 单库分表 —— 添加
+     * @return
+     */
+    @PostMapping(value = "/test1")
+    @ApiOperation(value = "单库分表插入", notes = "单库分表")
+    public Result<?> add() {
+        log.info("---------------------------------单库分表插入--------------------------------");
+        int size = 10;
+        for (int i = 0; i < size; i++) {
+            ShardingSysLog shardingSysLog = new ShardingSysLog();
+            shardingSysLog.setLogContent("jeecg");
+            shardingSysLog.setLogType(i);
+            shardingSysLog.setOperateType(i);
+            shardingSysLogService.save(shardingSysLog);
+        }
+        return Result.OK("单库分表插入10条数据完成!");
+    }
+
+    /**
+     * 单库分表 —— 查询
+     * @return
+     */
+    @PostMapping(value = "/list1")
+    @ApiOperation(value = "单库分表查询", notes = "单库分表")
+    public Result<?> list() {
+        return Result.OK(shardingSysLogService.list());
+    }
+
+    /**
+     * 分库分表 - 插入
+     * @return
+     */
+    @PostMapping(value = "/test2")
+    @ApiOperation(value = "分库分表插入", notes = "分库分表")
+    public Result<?> test2() {
+        int start=20;
+        int size=30;
+        for (int i = start; i <= size; i++) {
+            ShardingSysLog shardingSysLog = new ShardingSysLog();
+            shardingSysLog.setLogContent("分库分表测试");
+            shardingSysLog.setLogType(0);
+            shardingSysLog.setOperateType(i);
+            shardingSysLogService.save(shardingSysLog);
+        }
+        return Result.OK("分库分表插入10条数据完成!");
+    }
+
+    /**
+     * 分库分表 - 查询
+     * @return
+     */
+    @PostMapping(value = "/list2")
+    @ApiOperation(value = "分库分表查询", notes = "分库分表")
+    public Result<?> list2() {
+        return Result.OK(shardingSysLogService.list());
+    }
+
+}

+ 72 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/controller/JobApiController.java

@@ -0,0 +1,72 @@
+package com.xxl.job.admin.controller;
+
+import com.xxl.job.admin.controller.annotation.PermissionLimit;
+import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
+import com.xxl.job.core.biz.AdminBiz;
+import com.xxl.job.core.biz.model.HandleCallbackParam;
+import com.xxl.job.core.biz.model.RegistryParam;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.util.GsonTool;
+import com.xxl.job.core.util.XxlJobRemotingUtil;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/5/10.
+ */
+@Controller
+@RequestMapping("/api")
+public class JobApiController {
+
+    @Resource
+    private AdminBiz adminBiz;
+
+    /**
+     * api
+     *
+     * @param uri
+     * @param data
+     * @return
+     */
+    @RequestMapping("/{uri}")
+    @ResponseBody
+    @PermissionLimit(limit=false)
+    public ReturnT<String> api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) {
+
+        // valid
+        if (!"POST".equalsIgnoreCase(request.getMethod())) {
+            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support.");
+        }
+        if (uri==null || uri.trim().length()==0) {
+            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty.");
+        }
+        if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null
+                && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0
+                && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
+            return new ReturnT<String>(ReturnT.FAIL_CODE, "The access token is wrong.");
+        }
+
+        // services mapping
+        if ("callback".equals(uri)) {
+            List<HandleCallbackParam> callbackParamList = GsonTool.fromJson(data, List.class, HandleCallbackParam.class);
+            return adminBiz.callback(callbackParamList);
+        } else if ("registry".equals(uri)) {
+            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
+            return adminBiz.registry(registryParam);
+        } else if ("registryRemove".equals(uri)) {
+            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
+            return adminBiz.registryRemove(registryParam);
+        } else {
+            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping("+ uri +") not found.");
+        }
+
+    }
+
+}

+ 20 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/core/alarm/JobAlarm.java

@@ -0,0 +1,20 @@
+package com.xxl.job.admin.core.alarm;
+
+import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.model.XxlJobLog;
+
+/**
+ * @author xuxueli 2020-01-19
+ */
+public interface JobAlarm {
+
+    /**
+     * job alarm
+     *
+     * @param info
+     * @param jobLog
+     * @return
+     */
+    public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog);
+
+}

+ 65 - 0
jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java

@@ -0,0 +1,65 @@
+package com.xxl.job.admin.core.alarm;
+
+import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.model.XxlJobLog;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class JobAlarmer implements ApplicationContextAware, InitializingBean {
+    private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class);
+
+    private ApplicationContext applicationContext;
+    private List<JobAlarm> jobAlarmList;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        Map<String, JobAlarm> serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class);
+        if (serviceBeanMap != null && serviceBeanMap.size() > 0) {
+            jobAlarmList = new ArrayList<JobAlarm>(serviceBeanMap.values());
+        }
+    }
+
+    /**
+     * job alarm
+     *
+     * @param info
+     * @param jobLog
+     * @return
+     */
+    public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) {
+
+        boolean result = false;
+        if (jobAlarmList!=null && jobAlarmList.size()>0) {
+            result = true;  // success means all-success
+            for (JobAlarm alarm: jobAlarmList) {
+                boolean resultItem = false;
+                try {
+                    resultItem = alarm.doAlarm(info, jobLog);
+                } catch (Exception e) {
+                    logger.error(e.getMessage(), e);
+                }
+                if (!resultItem) {
+                    result = false;
+                }
+            }
+        }
+
+        return result;
+    }
+
+}