├── src ├── main │ ├── resources │ │ ├── dashboard.json │ │ ├── templates │ │ │ ├── 403.html │ │ │ ├── mail │ │ │ │ └── emailTemplate.html │ │ │ ├── download.html │ │ │ ├── index.html │ │ │ └── login.html │ │ ├── db │ │ │ └── migration │ │ │ │ ├── V1__init.sql │ │ │ │ └── V2__init_tables.sql │ │ ├── properties │ │ │ ├── global.properties │ │ │ ├── release │ │ │ │ ├── global.properties │ │ │ │ └── log.properties │ │ │ ├── quartz.properties │ │ │ └── log.properties │ │ ├── static │ │ │ └── project │ │ │ │ ├── html │ │ │ │ ├── demo.html │ │ │ │ ├── demo │ │ │ │ │ ├── bottom-sheet.html │ │ │ │ │ ├── dashboard.html │ │ │ │ │ ├── metric.html │ │ │ │ │ ├── sidenav │ │ │ │ │ │ ├── sidenav.html │ │ │ │ │ │ └── sidenav-info.html │ │ │ │ │ ├── file.html │ │ │ │ │ ├── notification.html │ │ │ │ │ ├── buttons.html │ │ │ │ │ ├── drag.html │ │ │ │ │ ├── information.html │ │ │ │ │ ├── tree.html │ │ │ │ │ ├── stepper.html │ │ │ │ │ ├── form.html │ │ │ │ │ ├── choose.html │ │ │ │ │ ├── dialog-form.html │ │ │ │ │ └── table.html │ │ │ │ └── switch-source.html │ │ │ │ ├── css │ │ │ │ └── project-style.css │ │ │ │ └── js │ │ │ │ └── app.js │ │ ├── application.properties │ │ ├── generatorConfig.xml │ │ ├── permission.json │ │ ├── logback.xml │ │ └── menu.json │ └── java │ │ └── com │ │ └── fit2cloud │ │ └── demo │ │ ├── common │ │ └── constants │ │ │ └── PermissionConstants.java │ │ ├── job │ │ └── SyncDemo.java │ │ ├── dao │ │ ├── optional │ │ │ └── OptionalDemoMapper.java │ │ └── primary │ │ │ ├── DemoMapper.java │ │ │ └── DemoMapper.xml │ │ ├── init │ │ ├── CustomRunner.java │ │ └── ListenStartedEvent.java │ │ ├── config │ │ ├── CommonConfig.java │ │ ├── CustomDBEncryptConfig.java │ │ ├── ShiroConfig.java │ │ ├── OptionalMybatisConfig.java │ │ └── MybatisConfig.java │ │ ├── Application.java │ │ ├── controller │ │ ├── DemoController.java │ │ ├── IndexController.java │ │ └── LoginController.java │ │ └── model │ │ ├── Demo.java │ │ └── DemoExample.java └── test │ └── java │ └── com │ └── fit2cloud │ └── demo │ ├── ApplicationTests.java │ └── MultiDataSourceTest.java ├── service.ico ├── service.inf ├── .gitignore ├── Dockerfile ├── docker-compose.yml ├── README.md └── pom.xml /src/main/resources/dashboard.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /src/main/resources/templates/403.html: -------------------------------------------------------------------------------- 1 | 无权限,哈哈哈 -------------------------------------------------------------------------------- /src/main/resources/db/migration/V1__init.sql: -------------------------------------------------------------------------------- 1 | select database(); -------------------------------------------------------------------------------- /src/main/resources/properties/global.properties: -------------------------------------------------------------------------------- 1 | run.mode=local -------------------------------------------------------------------------------- /src/main/resources/properties/release/global.properties: -------------------------------------------------------------------------------- 1 | run.mode=release -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo.html: -------------------------------------------------------------------------------- 1 | adfdsad -------------------------------------------------------------------------------- /src/main/resources/properties/quartz.properties: -------------------------------------------------------------------------------- 1 | cron.expression.demo=1/5 * * * * ? -------------------------------------------------------------------------------- /src/main/resources/properties/log.properties: -------------------------------------------------------------------------------- 1 | log.level.sql=DEBUG 2 | log.out=console 3 | -------------------------------------------------------------------------------- /service.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fit2cloudrd/fit2cloud2.0-module-demo/HEAD/service.ico -------------------------------------------------------------------------------- /src/main/resources/properties/release/log.properties: -------------------------------------------------------------------------------- 1 | log.level.sql=ERROR 2 | log.out=debugAsyncAppender 3 | -------------------------------------------------------------------------------- /service.inf: -------------------------------------------------------------------------------- 1 | name=模板工程服务 2 | description=FIT2CLOUD 云管平台 2.0 的扩展模块示例工程。 3 | minimumFit2cloudVersion=V2.0.60 4 | version=2.0.0 5 | version= 6 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/common/constants/PermissionConstants.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.common.constants; 2 | 3 | public class PermissionConstants { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/bottom-sheet.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{msg}} 4 |
5 |
6 | -------------------------------------------------------------------------------- /src/main/resources/db/migration/V2__init_tables.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `demo` ( 2 | `id` varchar(50) NOT NULL COMMENT 'ID', 3 | `name` varchar(50) DEFAULT NULL COMMENT '名称', 4 | `create_time` bigint(15) DEFAULT NULL COMMENT '创建时间', 5 | PRIMARY KEY (`id`) 6 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -------------------------------------------------------------------------------- /src/main/resources/templates/mail/emailTemplate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 验证邮件 6 | 7 | 8 | 您好,这是验证邮件
9 | 激活账号 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/job/SyncDemo.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.job; 2 | 3 | import com.fit2cloud.quartz.anno.QuartzScheduled; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | public class SyncDemo { 8 | @QuartzScheduled(cron = "${cron.expression.demo}") 9 | public void syncCloudServer() { 10 | System.out.println("this is demo"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/dashboard.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
监控
5 |
6 |
7 |
8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/metric.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
监控
5 |
6 |
7 |
8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | 27 | ### NPM ### 28 | package-lock.json 29 | node_modules 30 | 31 | .DS_Store -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/dao/optional/OptionalDemoMapper.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.dao.optional; 2 | 3 | import com.fit2cloud.demo.model.Demo; 4 | import org.apache.ibatis.annotations.Select; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 请自行修改成xml模式 11 | */ 12 | @Repository 13 | public interface OptionalDemoMapper { 14 | @Select("SELECT * FROM user") 15 | List selectAll(); 16 | } 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fit2cloud.com/public/fabric8-java-alpine-openjdk8-jre:latest 2 | 3 | MAINTAINER FIT2CLOUD 4 | 5 | RUN mkdir -p /opt/apps 6 | 7 | ADD target/module-demo-2.0.0.jar /opt/apps 8 | 9 | ENV JAVA_APP_JAR=/opt/apps/module-demo-2.0.0.jar 10 | 11 | ENV AB_OFF=true 12 | 13 | ENV JAVA_OPTIONS=-Dfile.encoding=utf-8 14 | 15 | HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD curl -f 127.0.0.1:8080 16 | 17 | CMD ["/deployments/run-java.sh"] 18 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/init/CustomRunner.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.init; 2 | 3 | import org.springframework.boot.ApplicationArguments; 4 | import org.springframework.boot.ApplicationRunner; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * 程序启动后触发执行的逻辑 9 | */ 10 | @Component 11 | public class CustomRunner implements ApplicationRunner { 12 | @Override 13 | public void run(ApplicationArguments args) throws Exception { 14 | System.out.println("runner 启动执行"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | services: 3 | 4 | module-demo-service: 5 | image: registry.fit2cloud.com/fit2cloud2-extention/module-demo:latest 6 | container_name: module-demo-service 7 | volumes: 8 | - share-volume:/opt/fit2cloud/share 9 | - host-opt-fit2cloud-conf:/opt/fit2cloud/conf 10 | - host-opt-fit2cloud-logs:/opt/fit2cloud/logs 11 | mem_limit: 1024m 12 | depends_on: 13 | management-center: 14 | condition: service_healthy 15 | networks: 16 | - cmp-network 17 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/init/ListenStartedEvent.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.init; 2 | 3 | import org.springframework.boot.context.event.ApplicationStartedEvent; 4 | import org.springframework.context.event.EventListener; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * 程序启动后触发执行的逻辑 9 | */ 10 | @Component 11 | public class ListenStartedEvent { 12 | 13 | @EventListener 14 | public void init(ApplicationStartedEvent event) { 15 | System.out.println("event 启动执行"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/config/CommonConfig.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.PropertySource; 5 | 6 | /** 7 | * 8 | */ 9 | @PropertySource(value = { 10 | "file:/opt/fit2cloud/conf/fit2cloud.properties", 11 | "classpath:properties/global.properties", 12 | "classpath:properties/quartz.properties" 13 | }, encoding = "UTF-8", ignoreResourceNotFound = true) 14 | @Configuration 15 | public class CommonConfig { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/sidenav/sidenav.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | md-primary 5 |
6 |
7 | 9 |
10 |
11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/config/CustomDBEncryptConfig.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.config; 2 | 3 | import com.fit2cloud.commons.server.config.DBEncryptConfig; 4 | import com.fit2cloud.commons.utils.EncryptConfig; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * 配置加密 12 | */ 13 | @Component 14 | public class CustomDBEncryptConfig implements DBEncryptConfig { 15 | @Override 16 | public List encryptConfig() { 17 | return new ArrayList<>(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/file.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
文件
6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/Application.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | @SpringBootApplication(exclude = QuartzAutoConfiguration.class) 9 | @EnableDiscoveryClient 10 | public class Application { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(Application.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/notification.html: -------------------------------------------------------------------------------- 1 |
2 | Notification.show 3 | Notification.info 4 | Notification.success 5 | Notification.warn 6 | Notification.danger 7 | open 8 |
9 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/switch-source.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

切换

5 | 6 | 7 | close 8 | 9 |
10 |
11 | 12 | 13 | 14 | arrow_drop_down 15 | 16 | arrow_right 17 | 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ###spring.application.name 小写 2 | spring.application.name=fit2cloud-demo 3 | server.port=8080 4 | ###是否开启定时任务 5 | quartz.enabled=false 6 | quartz.scheduler-name=fit2cloud 7 | module.name=fit2cloud-demo 8 | module.icon=home 9 | module.order=20 10 | module.summary=fit2cloud-demo 11 | eureka.instance.metadata-map.server-name=${module.name} 12 | eureka.instance.metadata-map.enable-swagger=true 13 | eureka.client.enabled=false 14 | # flyway enable 15 | spring.flyway.enabled=true 16 | spring.flyway.baseline-on-migrate=true 17 | spring.flyway.locations=classpath:db/migration 18 | spring.flyway.table=demo_version 19 | spring.flyway.baseline-version=0 20 | spring.flyway.encoding=UTF-8 21 | spring.flyway.validate-on-migrate=false 22 | spring.flyway.placeholder-prefix=##( 23 | spring.flyway.placeholder-suffix=) 24 | 25 | logging.path=/opt/fit2cloud/logs/${spring.application.name} 26 | -------------------------------------------------------------------------------- /src/test/java/com/fit2cloud/demo/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo; 2 | 3 | import com.fit2cloud.commons.server.base.domain.CloudAccount; 4 | import com.fit2cloud.commons.server.base.mapper.CloudAccountMapper; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.List; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class ApplicationTests { 16 | @Resource 17 | private CloudAccountMapper cloudAccountMapper; 18 | 19 | @Test 20 | public void contextLoads() { 21 | List cloudAccounts = cloudAccountMapper.selectByExample(null); 22 | cloudAccounts.forEach(cloudAccount -> { 23 | System.out.println(cloudAccount.getCredential()); 24 | }); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/templates/download.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | angular下载 6 | 7 | 8 | 9 | 手动下载资源 10 |
11 | angular-material.min.css
12 | angular-animate.min.js
13 | angular-aria.min.js
14 | angular-messages.min.js
15 | angular-material.min.js
16 | jquery-3.3.1.min.js
17 | angular-ui-router.min.js
18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/controller/DemoController.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.controller; 2 | 3 | import com.fit2cloud.commons.server.handle.annotation.NoResultHolder; 4 | import com.fit2cloud.commons.utils.ResultHolder; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | 10 | @RestController 11 | @RequestMapping(value = "/demo") 12 | public class DemoController { 13 | 14 | @RequestMapping(value = "/test1/{module}") 15 | public ResultHolder resultHolder1(@PathVariable String module) throws InterruptedException { 16 | Thread.sleep(Integer.valueOf(module)); 17 | return ResultHolder.success(module); 18 | } 19 | 20 | @RequestMapping(value = "/test2/{module}") 21 | public String resultHolder2(@PathVariable String module) { 22 | return module; 23 | } 24 | 25 | 26 | @RequestMapping(value = "/test3/{module}") 27 | @NoResultHolder 28 | public String resultHolder3(@PathVariable String module) { 29 | return module; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/buttons.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | md-primary 4 | md-accent 5 | md-success 6 | md-warn 7 | 默认 8 |
9 | 10 |
11 | md-primary 12 | md-accent 13 | md-success 14 | md-warn 15 | 默认 16 |
17 | 18 |
19 | md-primary 20 | md-accent 21 | md-success 22 | md-warn 23 | 默认 24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/drag.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
拖拽
5 |
6 |
7 |
8 |
9 |
10 |
11 | 交换 12 |
13 |
14 | 15 | 16 |

{{item.name}}

17 |
18 |
19 |
20 |
21 |
22 |
23 | 插入 24 |
25 |
26 | 27 | 28 |

{{item.name}}

29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/information.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
信息
5 |
6 | 7 |
关闭信息
8 |
9 |
10 |
11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 是否启用 32 | 33 |
34 |
-------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.controller; 2 | 3 | import com.fit2cloud.commons.server.constants.WebConstants; 4 | import com.fit2cloud.commons.server.constants.IndexConstants; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.servlet.ModelAndView; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | @Controller 14 | public class IndexController { 15 | 16 | /** 17 | * 跳转到无Header主页 18 | */ 19 | @RequestMapping(value = "/", method = RequestMethod.GET) 20 | public ModelAndView index(HttpServletRequest request) { 21 | ModelAndView modelAndView = new ModelAndView(); 22 | modelAndView.addObject("timestamp", WebConstants.timestamp); 23 | String banner = request.getParameter(IndexConstants.BANNER); 24 | if (StringUtils.equals(banner, IndexConstants.BANNER_FALSE)) { 25 | modelAndView.setViewName("index"); 26 | } else { 27 | modelAndView.setViewName("web-public/index"); 28 | } 29 | return modelAndView; 30 | } 31 | 32 | @RequestMapping(value = "/swagger", method = RequestMethod.GET) 33 | public String swagger() { 34 | return "swagger"; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/static/project/css/project-style.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * 项目CSS,有特殊需求就写在这里。 3 | **/ 4 | 5 | /*! 6 | * 项目CSS,有特殊需求就写在这里。 7 | **/ 8 | 9 | 10 | table.db { 11 | font-size: 13px; 12 | font-weight: 400; 13 | letter-spacing: .01em; 14 | line-height: 20px; 15 | width: 100%; 16 | text-align: left; 17 | border: 0; 18 | border-collapse: collapse; 19 | border-spacing: 0; 20 | margin: 0; 21 | outline: 0; 22 | padding: 0; 23 | vertical-align: baseline; 24 | } 25 | 26 | table.db tbody, thead, tr { 27 | border: 0; 28 | font-family: inherit; 29 | font-size: 100%; 30 | font-style: inherit; 31 | font-weight: inherit; 32 | margin: 0; 33 | outline: 0; 34 | padding: 0; 35 | vertical-align: baseline; 36 | } 37 | 38 | table.db td { 39 | max-width: none; 40 | min-width: 0px; 41 | white-space: normal; 42 | position: relative; 43 | vertical-align: top; 44 | word-wrap: break-word; 45 | padding: 4px 16px; 46 | text-align: left; 47 | width: auto; 48 | } 49 | 50 | 51 | .item-info { 52 | border: 1px solid #DFDFDF; 53 | margin-bottom: 10px; 54 | width: calc(100% - 2px); 55 | } 56 | 57 | .item-info .table > tbody > tr:nth-child(odd) { 58 | background-color: white; 59 | } 60 | 61 | .item-info .table > tbody > tr > td { 62 | border-top: 1px solid #DFDFDF; 63 | } 64 | 65 | .item-info .item-info-label { 66 | font-weight: bold; 67 | text-align: right; 68 | width: 30%; 69 | } 70 | 71 | .item-info .item-info-value { 72 | text-align: left; 73 | width: 70%; 74 | padding-left: 20px; 75 | } -------------------------------------------------------------------------------- /src/test/java/com/fit2cloud/demo/MultiDataSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo; 2 | 3 | import com.fit2cloud.commons.server.base.domain.User; 4 | import com.fit2cloud.commons.server.base.mapper.UserMapper; 5 | import com.fit2cloud.demo.dao.optional.OptionalDemoMapper; 6 | import com.fit2cloud.demo.dao.primary.DemoMapper; 7 | import com.fit2cloud.demo.model.Demo; 8 | import com.github.pagehelper.Page; 9 | import com.github.pagehelper.PageHelper; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | import javax.annotation.Resource; 16 | import java.util.List; 17 | 18 | @RunWith(SpringRunner.class) 19 | @SpringBootTest 20 | public class MultiDataSourceTest { 21 | 22 | @Resource 23 | private DemoMapper demoMapper; 24 | @Resource 25 | private UserMapper userMapper; 26 | @Resource 27 | private OptionalDemoMapper optionalDemoMapper; 28 | 29 | @Test 30 | public void testMultiDataSource() { 31 | List demos = demoMapper.selectByExample(null); 32 | System.out.println(demos.size()); 33 | 34 | List demoList = optionalDemoMapper.selectAll(); 35 | System.out.println(demoList.size()); 36 | } 37 | 38 | @Test 39 | public void testPageable() { 40 | Page page = PageHelper.startPage(1, 1, true); 41 | List userList = userMapper.selectByExample(null); 42 | System.out.println(userList.size()); 43 | 44 | page = PageHelper.startPage(1, 1, true); 45 | List demoList = optionalDemoMapper.selectAll(); 46 | System.out.println(demoList.size()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/tree.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 | done 8 | 获取已选择 9 | 10 |
11 |
12 |
13 |
14 |
15 |
16 | 单选,结果:{{radio.selected}} 17 |
18 | 19 |
20 |
21 |
22 | 单选,结果:{{radio.selected}} 23 |
24 | 25 |
26 |
27 |
28 | 带根节点 29 |
30 | 31 |
32 |
33 |
34 | 不带根节点 35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/stepper.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
Stepper
5 | 6 | open_in_browser 7 | 打开向导 8 | 9 |
10 |
11 | 12 |
13 | 14 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
15 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
16 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
17 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
18 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
19 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
20 | aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
21 |
22 | 23 | 2222 24 | 25 | 26 | 异步验证 27 | 28 | 29 | 4444 30 | 31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.config; 2 | 3 | 4 | import com.fit2cloud.commons.server.security.SsoFilter; 5 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 6 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import java.util.Map; 11 | 12 | @Configuration 13 | public class ShiroConfig { 14 | 15 | @Bean 16 | public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager sessionManager) { 17 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 18 | shiroFilterFactoryBean.setSecurityManager(sessionManager); 19 | shiroFilterFactoryBean.setLoginUrl("/login"); 20 | shiroFilterFactoryBean.setUnauthorizedUrl("/403"); 21 | shiroFilterFactoryBean.setSuccessUrl("/"); 22 | 23 | shiroFilterFactoryBean.getFilters().put("sso", new SsoFilter()); 24 | 25 | Map filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap(); 26 | filterChainDefinitionMap.put("/resource/**", "anon"); 27 | filterChainDefinitionMap.put("/login", "sso, anon"); 28 | filterChainDefinitionMap.put("/eureka/**", "anon"); 29 | filterChainDefinitionMap.put("/web-public/**", "anon"); 30 | filterChainDefinitionMap.put("/project/**", "anon"); 31 | 32 | // for swagger 33 | filterChainDefinitionMap.put("/swagger-ui.html", "anon"); 34 | filterChainDefinitionMap.put("/swagger-resources/**", "anon"); 35 | filterChainDefinitionMap.put("/webjars/**", "anon"); 36 | filterChainDefinitionMap.put("/v2/api-docs", "anon"); 37 | 38 | filterChainDefinitionMap.put("/api/**", "anon"); 39 | filterChainDefinitionMap.put("/403", "anon"); 40 | filterChainDefinitionMap.put("/anonymous/**", "anon"); 41 | filterChainDefinitionMap.put("/**", "sso, authc"); 42 | return shiroFilterFactoryBean; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/form.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
Test Form
5 |
6 |
7 | 8 |
9 |
10 | 11 | 12 | 13 |
14 |
必填.
15 |
不要超过30个字符
16 |
17 |
18 | 19 | 20 | 21 | 22 |
23 |
必填.
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 |
邮箱将用做登录的唯一标识
32 |
33 |
34 | 邮件必须符合邮件格式,并且在10-100字符以内 35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 是否启用 43 | 44 |
45 |
46 | 47 | 保存 48 | 49 | 50 | 取消 51 | 52 |
53 |
54 |
-------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 | 29 |
30 |
31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/choose.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
选择
5 |
6 |
7 | 8 |
9 |
10 |
11 | 不设置宽读和高度:宽度100%(最小宽度400px),高度根据内容变化(最小高度300px),selected为所选对象的主键(key="id") 12 |
13 | 14 |
15 | 结果 16 |
17 | {{selected}} 18 |
19 |
20 |
21 | 设置宽读和高度:宽度500px(最小宽度400px),高度400px(最小高度300px),selected为所选对象 22 |
23 | 25 |
26 | 结果 27 |
28 | {{selected2}} 29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | {{param.name}} 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | {{param.name}} 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | {{param.name}} 59 | 60 | 61 | 62 |
63 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/dialog-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |

Test Form

7 | 8 | 9 | close 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 | 20 |
21 |
必填.
22 |
不要超过30个字符
23 |
24 |
25 | 26 | 27 | 28 | 29 |
30 |
必填.
31 |
32 |
33 |
34 | 35 | 36 | 37 | 39 | 40 |
邮箱将用做登录的唯一标识
41 | 42 |
43 |
44 | 邮件必须符合邮件格式,并且在10-100字符以内 45 |
46 |
47 |
48 |
49 |
50 | 51 | 52 | 53 | 确定 54 | 55 | 56 | 取消 57 | 58 | 59 |
60 |
-------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/model/Demo.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.model; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import java.io.Serializable; 5 | 6 | public class Demo implements Serializable { 7 | @ApiModelProperty("ID") 8 | private String id; 9 | 10 | @ApiModelProperty("名称") 11 | private String name; 12 | 13 | @ApiModelProperty("创建时间") 14 | private Long createTime; 15 | 16 | /** 17 | * This field was generated by MyBatis Generator. 18 | * This field corresponds to the database table demo 19 | * 20 | * @mbg.generated 21 | */ 22 | private static final long serialVersionUID = 1L; 23 | 24 | /** 25 | * This method was generated by MyBatis Generator. 26 | * This method returns the value of the database column demo.id 27 | * 28 | * @return the value of demo.id 29 | * 30 | * @mbg.generated 31 | */ 32 | public String getId() { 33 | return id; 34 | } 35 | 36 | /** 37 | * This method was generated by MyBatis Generator. 38 | * This method sets the value of the database column demo.id 39 | * 40 | * @param id the value for demo.id 41 | * 42 | * @mbg.generated 43 | */ 44 | public void setId(String id) { 45 | this.id = id == null ? null : id.trim(); 46 | } 47 | 48 | /** 49 | * This method was generated by MyBatis Generator. 50 | * This method returns the value of the database column demo.name 51 | * 52 | * @return the value of demo.name 53 | * 54 | * @mbg.generated 55 | */ 56 | public String getName() { 57 | return name; 58 | } 59 | 60 | /** 61 | * This method was generated by MyBatis Generator. 62 | * This method sets the value of the database column demo.name 63 | * 64 | * @param name the value for demo.name 65 | * 66 | * @mbg.generated 67 | */ 68 | public void setName(String name) { 69 | this.name = name == null ? null : name.trim(); 70 | } 71 | 72 | /** 73 | * This method was generated by MyBatis Generator. 74 | * This method returns the value of the database column demo.create_time 75 | * 76 | * @return the value of demo.create_time 77 | * 78 | * @mbg.generated 79 | */ 80 | public Long getCreateTime() { 81 | return createTime; 82 | } 83 | 84 | /** 85 | * This method was generated by MyBatis Generator. 86 | * This method sets the value of the database column demo.create_time 87 | * 88 | * @param createTime the value for demo.create_time 89 | * 90 | * @mbg.generated 91 | */ 92 | public void setCreateTime(Long createTime) { 93 | this.createTime = createTime; 94 | } 95 | } -------------------------------------------------------------------------------- /src/main/resources/generatorConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/dao/primary/DemoMapper.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.dao.primary; 2 | 3 | import com.fit2cloud.demo.model.Demo; 4 | import com.fit2cloud.demo.model.DemoExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface DemoMapper { 10 | /** 11 | * This method was generated by MyBatis Generator. 12 | * This method corresponds to the database table demo 13 | * 14 | * @mbg.generated 15 | */ 16 | long countByExample(DemoExample example); 17 | 18 | /** 19 | * This method was generated by MyBatis Generator. 20 | * This method corresponds to the database table demo 21 | * 22 | * @mbg.generated 23 | */ 24 | int deleteByExample(DemoExample example); 25 | 26 | /** 27 | * This method was generated by MyBatis Generator. 28 | * This method corresponds to the database table demo 29 | * 30 | * @mbg.generated 31 | */ 32 | int deleteByPrimaryKey(String id); 33 | 34 | /** 35 | * This method was generated by MyBatis Generator. 36 | * This method corresponds to the database table demo 37 | * 38 | * @mbg.generated 39 | */ 40 | int insert(Demo record); 41 | 42 | /** 43 | * This method was generated by MyBatis Generator. 44 | * This method corresponds to the database table demo 45 | * 46 | * @mbg.generated 47 | */ 48 | int insertSelective(Demo record); 49 | 50 | /** 51 | * This method was generated by MyBatis Generator. 52 | * This method corresponds to the database table demo 53 | * 54 | * @mbg.generated 55 | */ 56 | List selectByExample(DemoExample example); 57 | 58 | /** 59 | * This method was generated by MyBatis Generator. 60 | * This method corresponds to the database table demo 61 | * 62 | * @mbg.generated 63 | */ 64 | Demo selectByPrimaryKey(String id); 65 | 66 | /** 67 | * This method was generated by MyBatis Generator. 68 | * This method corresponds to the database table demo 69 | * 70 | * @mbg.generated 71 | */ 72 | int updateByExampleSelective(@Param("record") Demo record, @Param("example") DemoExample example); 73 | 74 | /** 75 | * This method was generated by MyBatis Generator. 76 | * This method corresponds to the database table demo 77 | * 78 | * @mbg.generated 79 | */ 80 | int updateByExample(@Param("record") Demo record, @Param("example") DemoExample example); 81 | 82 | /** 83 | * This method was generated by MyBatis Generator. 84 | * This method corresponds to the database table demo 85 | * 86 | * @mbg.generated 87 | */ 88 | int updateByPrimaryKeySelective(Demo record); 89 | 90 | /** 91 | * This method was generated by MyBatis Generator. 92 | * This method corresponds to the database table demo 93 | * 94 | * @mbg.generated 95 | */ 96 | int updateByPrimaryKey(Demo record); 97 | } -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/config/OptionalMybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.config; 2 | 3 | import com.github.pagehelper.PageInterceptor; 4 | import com.mchange.v2.c3p0.ComboPooledDataSource; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; 10 | import org.springframework.beans.factory.annotation.Qualifier; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.core.env.Environment; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | 16 | import javax.annotation.Resource; 17 | import javax.sql.DataSource; 18 | import java.util.Properties; 19 | 20 | /** 21 | * spring-boot集成mybatis的基本入口 22 | * 1)创建数据源 23 | * 2)创建SqlSessionFactory 24 | */ 25 | @Configuration //该注解类似于spring配置文件 26 | @MapperScan(basePackages = {"com.fit2cloud.demo.dao.optional"}, sqlSessionFactoryRef = "optionalSqlSessionFactory") 27 | @EnableTransactionManagement 28 | public class OptionalMybatisConfig { 29 | @Resource 30 | private Environment env; // 保存了配置文件的信息 31 | 32 | /** 33 | * 创建数据源 34 | */ 35 | @Bean 36 | // @QuartzDataSource // 指定 quartz 的数据库连接池 37 | public DataSource optionalDataSource() throws Exception { 38 | ComboPooledDataSource dataSource = new ComboPooledDataSource(); 39 | dataSource.setUser(env.getProperty("optional.rdb.user")); 40 | dataSource.setDriverClass(env.getProperty("optional.rdb.driver")); 41 | dataSource.setPassword(env.getProperty("optional.rdb.password")); 42 | dataSource.setJdbcUrl(env.getProperty("optional.rdb.url")); 43 | // todo 自行添加其他参数 44 | return dataSource; 45 | } 46 | 47 | @Bean 48 | public SqlSessionFactory optionalSqlSessionFactory(@Qualifier("optionalDataSource") DataSource optionalDataSource, 49 | @Qualifier("optionalPageInterceptor") PageInterceptor pageInterceptor) throws Exception { 50 | SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); 51 | factory.setDataSource(optionalDataSource); 52 | factory.setVfs(SpringBootVFS.class); 53 | // todo 自行添加其他参数 54 | // 分页插件需要写在第一个,具体原因看 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Interceptor.md 55 | Interceptor[] plugins = new Interceptor[]{pageInterceptor}; 56 | factory.setPlugins(plugins); 57 | return factory.getObject(); 58 | } 59 | 60 | /** 61 | * 多数据源需要定义自己的插件体系 62 | * 63 | * @return page helper 64 | */ 65 | @Bean 66 | public PageInterceptor optionalPageInterceptor() { 67 | PageInterceptor pageInterceptor = new PageInterceptor(); 68 | Properties properties = new Properties(); 69 | properties.setProperty("helperDialect", "mysql");// 有可能是其他数据库类型 oracle, pg, etc. 70 | properties.setProperty("rowBoundsWithCount", "true"); 71 | properties.setProperty("reasonable", "true"); 72 | properties.setProperty("offsetAsPageNum", "true"); 73 | properties.setProperty("pageSizeZero", "true"); 74 | pageInterceptor.setProperties(properties); 75 | return pageInterceptor; 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/main/resources/permission.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "permissions": [ 4 | { 5 | "id": "DEMO:DASHBOARD", 6 | "name": "仪盘表", 7 | "resourceId": "DEMO", 8 | "parentRoles": [ 9 | "ADMIN", 10 | "ORGADMIN", 11 | "USER" 12 | ] 13 | }, 14 | { 15 | "id": "DEMO:TABLE", 16 | "name": "table", 17 | "resourceId": "DEMO", 18 | "parentRoles": [ 19 | "ADMIN", 20 | "ORGADMIN", 21 | "USER" 22 | ] 23 | }, 24 | { 25 | "id": "DEMO:STEPPER", 26 | "name": "stepper", 27 | "resourceId": "DEMO", 28 | "parentRoles": [ 29 | "ADMIN", 30 | "ORGADMIN", 31 | "USER" 32 | ] 33 | }, 34 | { 35 | "id": "DEMO:BUTTON", 36 | "name": "button", 37 | "resourceId": "DEMO", 38 | "parentRoles": [ 39 | "ADMIN", 40 | "ORGADMIN", 41 | "USER" 42 | ] 43 | }, 44 | { 45 | "id": "DEMO:TREE", 46 | "name": "tree", 47 | "resourceId": "DEMO", 48 | "parentRoles": [ 49 | "ADMIN", 50 | "ORGADMIN", 51 | "USER" 52 | ] 53 | }, 54 | { 55 | "id": "DEMO:NOTICE", 56 | "name": "notice", 57 | "resourceId": "DEMO", 58 | "parentRoles": [ 59 | "ADMIN", 60 | "ORGADMIN", 61 | "USER" 62 | ] 63 | }, 64 | { 65 | "id": "DEMO:CHOOSE", 66 | "name": "choose", 67 | "resourceId": "DEMO", 68 | "parentRoles": [ 69 | "ADMIN", 70 | "ORGADMIN", 71 | "USER" 72 | ] 73 | }, 74 | { 75 | "id": "DEMO:DRAG", 76 | "name": "drag", 77 | "resourceId": "DEMO", 78 | "parentRoles": [ 79 | "ADMIN", 80 | "ORGADMIN", 81 | "USER" 82 | ] 83 | }, 84 | { 85 | "id": "DEMO:FILE", 86 | "name": "file", 87 | "resourceId": "DEMO", 88 | "parentRoles": [ 89 | "ADMIN", 90 | "ORGADMIN", 91 | "USER" 92 | ] 93 | }, 94 | { 95 | "id": "DEMO:LOADING", 96 | "name": "loading", 97 | "resourceId": "DEMO", 98 | "parentRoles": [ 99 | "ADMIN", 100 | "ORGADMIN", 101 | "USER" 102 | ] 103 | }, 104 | { 105 | "id": "DEMO:OTHER", 106 | "name": "other", 107 | "resourceId": "DEMO", 108 | "parentRoles": [ 109 | "ADMIN", 110 | "ORGADMIN", 111 | "USER" 112 | ] 113 | }, 114 | { 115 | "id": "FLOW:READ", 116 | "name": "查看流程", 117 | "resourceId": "FLOW", 118 | "parentRoles": [ 119 | "ADMIN" 120 | ] 121 | }, 122 | { 123 | "id": "FLOW:MANAGER", 124 | "name": "流程管理", 125 | "resourceId": "FLOW", 126 | "parentRoles": [ 127 | "ADMIN" 128 | ] 129 | }, 130 | { 131 | "id": "CLOUD_SERVER:READ", 132 | "name": "虚拟机监控", 133 | "resourceId": "CLOUD_SERVER", 134 | "parentRoles": [ 135 | "ADMIN", 136 | "ORGADMIN", 137 | "USER" 138 | ] 139 | } 140 | ], 141 | "resources": [ 142 | { 143 | "id": "DEMO", 144 | "name": "demo" 145 | }, 146 | { 147 | "id": "FLOW", 148 | "name": "流程管理" 149 | }, 150 | { 151 | "id": "CLOUD_SERVER", 152 | "name": "虚拟机" 153 | } 154 | ] 155 | } -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/config/MybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.config; 2 | 3 | import com.fit2cloud.commons.utils.DBEncryptInterceptor; 4 | import com.github.pagehelper.PageInterceptor; 5 | import com.mchange.v2.c3p0.ComboPooledDataSource; 6 | import org.apache.ibatis.plugin.Interceptor; 7 | import org.apache.ibatis.session.SqlSessionFactory; 8 | import org.mybatis.spring.SqlSessionFactoryBean; 9 | import org.mybatis.spring.annotation.MapperScan; 10 | import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; 11 | import org.springframework.beans.factory.annotation.Qualifier; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Primary; 15 | import org.springframework.core.env.Environment; 16 | import org.springframework.transaction.annotation.EnableTransactionManagement; 17 | 18 | import javax.annotation.Resource; 19 | import javax.sql.DataSource; 20 | import java.util.Properties; 21 | 22 | /** 23 | * spring-boot集成mybatis的基本入口 24 | * 1)创建数据源 25 | * 2)创建SqlSessionFactory 26 | */ 27 | @Configuration //该注解类似于spring配置文件 28 | @MapperScan(basePackages = {"com.fit2cloud.demo.dao.primary"}, sqlSessionFactoryRef = "sqlSessionFactory") 29 | @EnableTransactionManagement 30 | public class MybatisConfig { 31 | 32 | @Resource 33 | private Environment env; // 保存了配置文件的信息 34 | 35 | @Bean 36 | @Primary 37 | public DataSource dataSource() throws Exception { 38 | ComboPooledDataSource dataSource = new ComboPooledDataSource(); 39 | dataSource.setUser(env.getProperty("rdb.user")); 40 | dataSource.setDriverClass(env.getProperty("rdb.driver")); 41 | dataSource.setPassword(env.getProperty("rdb.password")); 42 | dataSource.setJdbcUrl(env.getProperty("rdb.url")); 43 | dataSource.setMaxIdleTime(1800); // 最大空闲时间 44 | dataSource.setAcquireIncrement(3);// 增长数 45 | dataSource.setInitialPoolSize(3);// 初始连接数 46 | dataSource.setMinPoolSize(3); // 最小连接数 47 | dataSource.setMaxPoolSize(30); // 默认连接数 48 | dataSource.setAcquireRetryAttempts(30);// 获取连接重试次数 49 | dataSource.setIdleConnectionTestPeriod(60); // 每60s检查数据库空闲连接 50 | dataSource.setMaxStatements(0); // c3p0全局的PreparedStatements缓存的大小 51 | dataSource.setBreakAfterAcquireFailure(false); // 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。Default: false 52 | dataSource.setTestConnectionOnCheckout(false); // 在每个connection 提交是校验有效性 53 | dataSource.setTestConnectionOnCheckin(true); // 取得连接的同时将校验连接的有效性 54 | return dataSource; 55 | } 56 | 57 | @Bean 58 | public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource, 59 | DBEncryptInterceptor dbEncryptInterceptor, 60 | @Qualifier("pageInterceptor") PageInterceptor pageInterceptor) throws Exception { 61 | SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); 62 | factory.setDataSource(dataSource); 63 | factory.setVfs(SpringBootVFS.class); 64 | // todo 自行添加其他参数 65 | // 分页插件需要写在第一个,具体原因看 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Interceptor.md 66 | Interceptor[] plugins = new Interceptor[]{pageInterceptor, dbEncryptInterceptor}; 67 | factory.setPlugins(plugins); 68 | return factory.getObject(); 69 | } 70 | 71 | /** 72 | * 多数据源需要定义自己的插件体系 73 | * 74 | * @return page helper 75 | */ 76 | @Bean 77 | public PageInterceptor pageInterceptor() { 78 | PageInterceptor pageInterceptor = new PageInterceptor(); 79 | Properties properties = new Properties(); 80 | properties.setProperty("helperDialect", "mysql"); 81 | properties.setProperty("rowBoundsWithCount", "true"); 82 | properties.setProperty("reasonable", "true"); 83 | properties.setProperty("offsetAsPageNum", "true"); 84 | properties.setProperty("pageSizeZero", "true"); 85 | pageInterceptor.setProperties(properties); 86 | return pageInterceptor; 87 | } 88 | 89 | } -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.controller; 2 | 3 | import com.fit2cloud.commons.server.constants.WebConstants; 4 | import com.fit2cloud.commons.server.utils.SessionUtils; 5 | import com.fit2cloud.commons.utils.GlobalConfigurations; 6 | import io.swagger.annotations.Api; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.apache.shiro.SecurityUtils; 9 | import org.apache.shiro.authc.AuthenticationException; 10 | import org.apache.shiro.authc.DisabledAccountException; 11 | import org.apache.shiro.authc.ExcessiveAttemptsException; 12 | import org.apache.shiro.authc.ExpiredCredentialsException; 13 | import org.apache.shiro.authc.IncorrectCredentialsException; 14 | import org.apache.shiro.authc.LockedAccountException; 15 | import org.apache.shiro.authc.UnknownAccountException; 16 | import org.apache.shiro.authc.UsernamePasswordToken; 17 | import org.apache.shiro.authz.UnauthorizedException; 18 | import org.apache.shiro.subject.Subject; 19 | import org.springframework.stereotype.Controller; 20 | import org.springframework.ui.Model; 21 | import org.springframework.web.bind.annotation.RequestMapping; 22 | import org.springframework.web.bind.annotation.RequestMethod; 23 | 24 | import javax.servlet.http.HttpServletRequest; 25 | import javax.servlet.http.HttpServletResponse; 26 | 27 | @Api(value = "Login", tags = {"login"}) 28 | @Controller 29 | @RequestMapping(headers = "Accept=application/json") 30 | public class LoginController { 31 | 32 | 33 | @RequestMapping(value = "/login", method = RequestMethod.GET) 34 | public Object login(HttpServletResponse response, Model model) { 35 | if (SessionUtils.getUser() == null) { 36 | return loginPath(response, model); 37 | } else { 38 | // 如果已经登录过,不用重新登录 39 | return "redirect:/"; 40 | } 41 | } 42 | 43 | @RequestMapping(value = "/login", method = RequestMethod.POST) 44 | public String login(String user, String password, HttpServletResponse response, Model model) { 45 | String msg; 46 | if (StringUtils.isBlank(user) || StringUtils.isBlank(password)) { 47 | msg = "user or password can't be null"; 48 | model.addAttribute("message", msg); 49 | return loginPath(response, model); 50 | } 51 | 52 | UsernamePasswordToken token = new UsernamePasswordToken(StringUtils.trim(user), StringUtils.trim(password)); 53 | Subject subject = SecurityUtils.getSubject(); 54 | 55 | try { 56 | subject.login(token); 57 | if (subject.isAuthenticated()) { 58 | return "redirect:/"; 59 | } else { 60 | model.addAttribute("message", ""); 61 | return loginPath(response, model); 62 | } 63 | } catch (IncorrectCredentialsException | UnknownAccountException e) { 64 | msg = e.getMessage(); 65 | } catch (ExcessiveAttemptsException e) { 66 | msg = "excessive attempts"; 67 | } catch (LockedAccountException e) { 68 | msg = "the user has been locked."; 69 | } catch (DisabledAccountException e) { 70 | msg = "the user has been disabled. "; 71 | } catch (ExpiredCredentialsException e) { 72 | msg = "user expires. "; 73 | } catch (UnauthorizedException e) { 74 | msg = "not authorized. " + e.getMessage(); 75 | } catch (AuthenticationException e) { 76 | msg = e.getMessage(); 77 | } 78 | model.addAttribute("message", msg); 79 | return loginPath(response, model); 80 | 81 | } 82 | 83 | @RequestMapping(value = "/logout", method = RequestMethod.GET) 84 | public String logout(HttpServletRequest request, HttpServletResponse response, Model model) { 85 | SecurityUtils.getSubject().logout(); 86 | return loginPath(response, model); 87 | } 88 | 89 | public String loginPath(HttpServletResponse response, Model model) { 90 | if (GlobalConfigurations.isReleaseMode()) { 91 | response.setHeader("Location", "/logout"); 92 | response.setStatus(302); 93 | } 94 | model.addAttribute("timestamp", WebConstants.timestamp); 95 | return "web-public/login"; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 登录 FIT2CLOUD 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FIT2CLOUD 云管平台 2.0 扩展模块的示范工程(模板工程) 2 | 3 | 4 | # 目录 5 | 6 | - [技能要求](#技能要求) 7 | - [代码规范](#代码规范) 8 | - [全局处理](#全局处理) 9 | - [本地环境运行与测试](#本地环境运行与测试) 10 | - [实际环境部署与升级](#实际环境部署与升级) 11 | 12 | ## 技能要求 13 | 14 | - 掌握 [Angular JS 1.7.2](https://angular.io/) 的内容(此框架的不同版本差异较大,本文基于用 1.7.2)。 15 | - 掌握 [Angular JS Material 1.1.9](https://material.angularjs.org/) 的内容。 16 | - 开发时如需自动提示 Angular 相关内容,可以 npm install angular@1.7.2 和 npm install angular-material, 安装后务必在 .gitignore 文件中添加package-lock.json 和 node_modules (Demo 17 | 工程已经添加) 18 | - 本项目使用 [Spring Boot 2.0](https://spring.io) 作为基础框架并集成 `thymeleaf` 、 `shiro` 、 `quartz` 和 `mail` 等功能。 19 | 20 | ## 代码规范 21 | 22 | - css, html, js等前端文件命名, 使用 `-` 做单词分隔,例如:fit2cloud-style.css, module-menu.html, angular-material.js 23 | - angular: Controller,Service 均使用大写首字母的驼峰命名,例如 MenuController, MenuService 24 | - angular: Directive,Component 均使用小写首字母的驼峰命名,例如 moduleMenu 25 | - js: 变量使用小写首字母的驼峰命名,例如 userName 26 | - js: 常量使用全大写,下划线分隔单词的命名,例如 var MAX_HEIGHT=1000 27 | 28 | 29 | ## 全局处理 30 | 31 | - 后台代码对 @RestController结果集进行了统一封装成 ResultHolder,如果自己返回 ResultHolder,则不会封装。如果需要包装的数据,method 返回类型不要是Object的(new Object()和 null 不会包装,1.返回的 type 不是 application/json 2.没有对应的 Object.class 的 HttpMessageConverter) 32 | - 如果不想返回结果被分装,可以在Controller的method上加@NoResultHolder注解 33 | - 后台代码做了全局异常处理 34 | - 前台 HttpUtils的 post, get 都做了错误处理(只有 ResultHolder 的 success 为 false 时,当做错误处理),如果需要重新定义错误可以用 error 的 function 接受,没有 error function 或自己弹出后台的错误信息 35 | - 在前端页面已经写的有 angular 的指令 36 | - has-permission:有这个权限的时候显示 单个权限 37 | - has-permissions:有其中一个权限的时候显示,主要是控制多个权限和去掉table的单选框、操作的列 38 | - lack-permission:没有这个权限的时候显示 39 | - lack-permissions:没有这里的所有权限的时候显示 40 | 41 | 42 | ## 本地环境编译、运行与测试 43 | 44 | ### 创建和初始化数据库 45 | 46 | 根据各自的情况创建数据库,执行下面的命令初始化 database: 47 | ``` 48 | CREATE DATABASE `fit2cloud` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; 49 | ``` 50 | 初始数据表可以从已安装的 FIT2CLOUD 2.0 云管平台服务器上导出。 51 | 52 | ### 创建本地2.0配置文件 53 | 54 | FIT2CLOUD 2.0 的配置文件存放路径为 /opt/fit2cloud/conf/fit2cloud.properties,拷贝以下内容并保存(相关组件的配置请参考实际情况进行设置): 55 | ``` 56 | #CMP DB configs 57 | rdb.driver=com.mysql.jdbc.Driver 58 | rdb.url=jdbc:mysql://localhost:3306/fit2cloud?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false 59 | rdb.user=root 60 | rdb.password=root 61 | 62 | #eureka 63 | eureka.client.service-url.defaultZone=http://localhost:6602/eureka/ 64 | 65 | #keycloak 66 | keycloak-server-address=http://localhost:8080/auth 67 | keycloak.auth-server-url=/auth/ 68 | keycloak.realm=cmp 69 | keycloak.public-client=true 70 | keycloak.resource=cmp-client 71 | 72 | #redis 73 | redis.hostname=localhost 74 | redis.password=fit2cloud 75 | redis.port=56379 76 | redis.database=2 77 | 78 | #elasticsearch 79 | spring.data.elasticsearch.cluster-name=fit2cloud-cmp-cluster 80 | spring.data.elasticsearch.cluster-nodes=localhost:9090 81 | 82 | logger.level=DEBUG 83 | 84 | prometheus.host=http://localhost:53340 85 | prometheus.pushgateway.host=localhost:53341 86 | ``` 87 | 88 | ### 修改 maven 配置文件 89 | 90 | 工程的运行需要的依赖包均存放在 FIT2CLOUD 提供的 Nexus 服务器上,下载这些依赖包需要在 maven 的 settings.xml 配置文件中,加上以下 server 的设置即可: 91 | ``` 92 | 93 | 94 | fit2cloud-enterprise-release 95 | readonly 96 | readonly@2018 97 | 98 | 99 | 100 | fit2cloud 101 | readonly 102 | readonly@2018 103 | 104 | ``` 105 | 106 | ### 编译 107 | 108 | 在工程目录下,执行 mvn clean package 即可对工程进行编译。 109 | 110 | ### 运行 111 | 112 | 在工程目录下,执行 mvn clean spring-boot:run 即可在本地将模块运行起来,默认端口为 8080,可以通过访问 http://localhost:8080 来访问服务。 113 | 114 | ### 测试 115 | 116 | 以 IDEA 为例,可以在 IDEA 的 maven 插件中,以 debug 模式运行工程进行调试。 117 | 118 | ## 实际环境部署与升级 119 | 120 | ### 工程文件说明 121 | 122 | 本工程为 FIT2CLOUD 2.0 标准扩展模块示例工程,工程目录下包含了制作扩展包所必需的文件: 123 | - Dockerfile - Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像 124 | - build.sh - FIT2CLOUD 提供的扩展包制作脚本,执行该脚本 125 | - docker-compose.yml - docker-compose.yml 文件是一个定义服务、网络和卷的 YAML 文件 126 | - service.ico - 扩展模块的图标文件 127 | - service.inf - 扩展模块的描述文件,包含模块名称、描述、模块版本、对 FIT2CLOUD 云管平台的最低版本要求等 128 | 129 | ### 扩展包的制作 130 | 131 | 实际部署时,根据具体情况修改好工程中的相关信息,执行 bash build.sh 即可生成扩展包和对应的 MD5 文件,例如 module-demo-2.0.0.tar.gz 和 module-demo-2.0.0.tar.gz.md5。 132 | 133 | ### 扩展包的安装与升级 134 | 135 | 在实际环境中部署扩展包,需要先在 [FIT2CLOUD 客户支持门户](https://support.fit2cloud.com)中下载 FIT2CLOUD 云管平台 2.0 的安装包及《FIT2CLOUD 云管平台2.0 安装及升级手册》,根据文档中的说明安装云管平台以及生成的扩展包。 136 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/table.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
表格
6 | 7 | add_circle_outline 8 | 创建 9 | 10 |
11 |
12 |
13 |
14 | 15 | 16 |
17 | 18 | 刷新 19 | refresh 20 | 21 |
22 |
23 | 24 | 帮助 25 | help 26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 | 34 | 37 | 40 | 41 | 42 | 43 | 73 | 74 | 75 |
35 | 36 | 38 | {{item.name}} 39 | {{item.created | date:'yyyy-MM-dd HH:mm'}}{{item.source}}{{item.email}} 44 | 45 | 46 | 47 | 48 | edit 49 | 弹窗编辑 50 | 51 | 52 | 53 | 54 | edit 55 | 侧边栏编辑 56 | 57 | 58 | 59 | 60 | content_copy 61 | 复制 62 | 63 | 64 | 65 | 66 | 67 | delete 68 | 删除 69 | 70 | 71 | 72 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/main/resources/static/project/html/demo/sidenav/sidenav-info.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
Sidenav-Info
5 |
6 | 关闭 7 |
8 |
9 |
10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
名称:测试
名称:测试
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
名称:测试
名称:测试
36 |
37 |
38 |
39 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
姓名性别年龄籍贯
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
FIT2CLOUD5浙江杭州
108 |
109 |
110 |
111 |
112 |
113 |
114 | 115 |
116 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %d %5p %40.40c:%4L - %m%n 10 | 11 | 12 | 13 | 15 | 16 | DEBUG 17 | ACCEPT 18 | DENY 19 | 20 | ${logging.path}/debug.log 21 | 22 | ${logging.path}/history/debug.%d{yyyyMMdd}-%i.log 23 | 24 | 30 25 | 27 | 50MB 28 | 29 | 30 | 31 | UTF-8 32 | %d [%thread] %-5level %logger{36} %line - %msg%n 33 | 34 | 35 | 36 | 38 | 39 | INFO 40 | 41 | ${logging.path}/info.log 42 | 43 | ${logging.path}/history/info.%d{yyyyMMdd}-%i.log 44 | 45 | 30 46 | 48 | 50MB 49 | 50 | 51 | 52 | UTF-8 53 | %d [%thread] %-5level %logger{36} %line - %msg%n 54 | 55 | 56 | 57 | 59 | 60 | ERROR 61 | ACCEPT 62 | DENY 63 | 64 | 65 | ${logging.path}/error.log 66 | 67 | ${logging.path}/history/error.%d{yyyyMMdd}-%i.log 68 | 69 | 30 70 | 72 | 50MB 73 | 74 | 75 | 76 | UTF-8 77 | %d [%thread] %-5level %logger{36} %line - %msg%n 78 | 79 | 80 | 81 | 83 | 84 | WARN 85 | ACCEPT 86 | DENY 87 | 88 | ${logging.path}/warn.log 89 | 90 | ${logging.path}/history/warn.%d{yyyyMMdd}-%i.log 91 | 92 | 30 93 | 95 | 50MB 96 | 97 | 98 | 99 | UTF-8 100 | %d [%thread] %-5level %logger{36} %line - %msg%n 101 | 102 | 103 | 104 | 106 | 107 | INFO 108 | 109 | ${logging.path}/login.log 110 | 111 | ${logging.path}/history/login.%d{yyyyMMdd}.log 112 | 113 | 30 114 | 115 | 116 | UTF-8 117 | %d %-5level - %msg%n 118 | 119 | 120 | 121 | 122 | 123 | DEBUG 124 | 125 | 10000 126 | 127 | 128 | 129 | 130 | 131 | DEBUG 132 | 133 | 10000 134 | 135 | 136 | 137 | 138 | 139 | INFO 140 | 141 | 10000 142 | 143 | 144 | 145 | 146 | 147 | ERROR 148 | 149 | 10000 150 | true 151 | 152 | 153 | 154 | 155 | 156 | WARN 157 | 158 | 10000 159 | true 160 | 161 | 162 | 163 | 164 | 165 | INFO 166 | 167 | 10000 168 | true 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/dao/primary/DemoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | and ${criterion.condition} 26 | 27 | 28 | and ${criterion.condition} #{criterion.value} 29 | 30 | 31 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 32 | 33 | 34 | and ${criterion.condition} 35 | 36 | #{listItem} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | and ${criterion.condition} 59 | 60 | 61 | and ${criterion.condition} #{criterion.value} 62 | 63 | 64 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 65 | 66 | 67 | and ${criterion.condition} 68 | 69 | #{listItem} 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 84 | id, name, create_time 85 | 86 | 104 | 114 | 115 | 119 | delete from demo 120 | where id = #{id,jdbcType=VARCHAR} 121 | 122 | 123 | 127 | delete from demo 128 | 129 | 130 | 131 | 132 | 133 | 137 | insert into demo (id, name, create_time 138 | ) 139 | values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT} 140 | ) 141 | 142 | 143 | 147 | insert into demo 148 | 149 | 150 | id, 151 | 152 | 153 | name, 154 | 155 | 156 | create_time, 157 | 158 | 159 | 160 | 161 | #{id,jdbcType=VARCHAR}, 162 | 163 | 164 | #{name,jdbcType=VARCHAR}, 165 | 166 | 167 | #{createTime,jdbcType=BIGINT}, 168 | 169 | 170 | 171 | 181 | 182 | 186 | update demo 187 | 188 | 189 | id = #{record.id,jdbcType=VARCHAR}, 190 | 191 | 192 | name = #{record.name,jdbcType=VARCHAR}, 193 | 194 | 195 | create_time = #{record.createTime,jdbcType=BIGINT}, 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 207 | update demo 208 | set id = #{record.id,jdbcType=VARCHAR}, 209 | name = #{record.name,jdbcType=VARCHAR}, 210 | create_time = #{record.createTime,jdbcType=BIGINT} 211 | 212 | 213 | 214 | 215 | 216 | 220 | update demo 221 | 222 | 223 | name = #{name,jdbcType=VARCHAR}, 224 | 225 | 226 | create_time = #{createTime,jdbcType=BIGINT}, 227 | 228 | 229 | where id = #{id,jdbcType=VARCHAR} 230 | 231 | 232 | 236 | update demo 237 | set name = #{name,jdbcType=VARCHAR}, 238 | create_time = #{createTime,jdbcType=BIGINT} 239 | where id = #{id,jdbcType=VARCHAR} 240 | 241 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.fit2cloud 7 | module-demo 8 | 2.0.0 9 | jar 10 | 11 | fit2cloud2.0-module-demo 12 | Module demo project for FIT2CLOUD 2.0 13 | 14 | 15 | commons-parent 16 | com.fit2cloud 17 | 2.0.0 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 2.0.0 24 | 0.0.6 25 | 1.8 26 | 27 | 28 | 29 | 30 | com.fit2cloud 31 | common-web 32 | ${fit2cloud-version} 33 | 34 | 35 | com.fit2cloud 36 | server-public 37 | ${fit2cloud-version} 38 | 39 | 40 | org.flywaydb 41 | flyway-core 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | io.springfox 50 | springfox-swagger-ui 51 | 2.9.0 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | src/main/java 60 | 61 | **/*.properties 62 | **/*.xml 63 | 64 | false 65 | 66 | 67 | src/main/resources 68 | 69 | **/*.* 70 | 71 | false 72 | 73 | 74 | 75 | 76 | org.codehaus.mojo 77 | buildnumber-maven-plugin 78 | 1.3 79 | 80 | 81 | validate 82 | 83 | create-timestamp 84 | 85 | 86 | 87 | 88 | {0,date,yyyy-MM-dd HH:mm:ss} 89 | 90 | timestamp 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-deploy-plugin 97 | 98 | false 99 | 100 | 101 | 102 | 103 | org.apache.maven.plugins 104 | maven-surefire-plugin 105 | 106 | true 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-enforcer-plugin 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-antrun-plugin 116 | 117 | 118 | properties-replace 119 | prepare-package 120 | 121 | 122 | 124 | 126 | 127 | 128 | 129 | run 130 | 131 | 132 | 133 | 134 | 135 | org.springframework.boot 136 | spring-boot-maven-plugin 137 | 138 | true 139 | 140 | 141 | 142 | org.apache.maven.plugins 143 | maven-compiler-plugin 144 | 145 | 1.8 146 | 1.8 147 | 148 | 149 | 150 | org.mybatis.generator 151 | mybatis-generator-maven-plugin 152 | 1.3.7 153 | 154 | true 155 | true 156 | 157 | 158 | 159 | com.fit2cloud 160 | tools 161 | 2.0.0 162 | 163 | 164 | mysql 165 | mysql-connector-java 166 | 5.1.41 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | spring-milestones 175 | Spring Milestones 176 | https://repo.spring.io/libs-milestone 177 | 178 | false 179 | 180 | 181 | 182 | jcenter-snapshots 183 | jcenter 184 | https://jcenter.bintray.com/ 185 | 186 | 187 | fit2cloud-enterprise-release 188 | Fit2Cloud Enterprise Release 189 | http://repository.fit2cloud.com/content/repositories/fit2cloud-enterprise-release/ 190 | 191 | true 192 | 193 | 194 | true 195 | 196 | 197 | 198 | fit2cloud 199 | fit2cloud 200 | http://repository.fit2cloud.com/content/groups/public/ 201 | 202 | true 203 | 204 | 205 | true 206 | 207 | 208 | 209 | 210 | 211 | fit2cloud 212 | fit2cloud 213 | http://repository.fit2cloud.com/content/groups/public/ 214 | 215 | true 216 | 217 | 218 | true 219 | 220 | 221 | 222 | 223 | 224 | releases 225 | Nexus Release Repository 226 | http://repository.fit2cloud.com/content/repositories/releases/ 227 | 228 | 229 | snapshots 230 | Nexus Snapshot Repository 231 | http://repository.fit2cloud.com/content/repositories/snapshots/ 232 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /src/main/resources/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "menu": [ 4 | { 5 | "order": 1, 6 | "title": "仪表盘", 7 | "icon": "account_box", 8 | "url": "/dashboard", 9 | "name": "dashboard", 10 | "templateUrl": "project/html/demo/dashboard.html", 11 | "requiredPermissions": [ 12 | { 13 | "role": "ADMIN", 14 | "logical": "OR", 15 | "permissions": [ 16 | "DEMO:DASHBOARD" 17 | ] 18 | }, 19 | { 20 | "role": "ORGADMIN", 21 | "logical": "OR", 22 | "permissions": [ 23 | "DEMO:DASHBOARD" 24 | ] 25 | }, 26 | { 27 | "role": "USER", 28 | "logical": "OR", 29 | "permissions": [ 30 | "DEMO:DASHBOARD" 31 | ] 32 | } 33 | ] 34 | }, 35 | { 36 | "order": 2, 37 | "title": "示例1", 38 | "icon": "cloud_queue", 39 | "children": [ 40 | { 41 | "order": 1, 42 | "title": "表格", 43 | "name": "table", 44 | "url": "/table", 45 | "templateUrl": "project/html/demo/table.html", 46 | "requiredPermissions": [ 47 | { 48 | "role": "ADMIN", 49 | "logical": "OR", 50 | "permissions": [ 51 | "DEMO:TABLE" 52 | ] 53 | }, 54 | { 55 | "role": "ORGADMIN", 56 | "logical": "OR", 57 | "permissions": [ 58 | "DEMO:TABLE" 59 | ] 60 | }, 61 | { 62 | "role": "USER", 63 | "logical": "OR", 64 | "permissions": [ 65 | "DEMO:TABLE" 66 | ] 67 | } 68 | ] 69 | }, 70 | { 71 | "order": 2, 72 | "title": "监控", 73 | "name": "metric", 74 | "url": "/metric", 75 | "templateUrl": "project/html/demo/metric.html", 76 | "requiredPermissions": [ 77 | { 78 | "role": "ADMIN", 79 | "logical": "OR", 80 | "permissions": [ 81 | "CLOUD_SERVER:READ" 82 | ] 83 | }, 84 | { 85 | "role": "ORGADMIN", 86 | "logical": "OR", 87 | "permissions": [ 88 | "CLOUD_SERVER:READ" 89 | ] 90 | }, 91 | { 92 | "role": "USER", 93 | "logical": "OR", 94 | "permissions": [ 95 | "CLOUD_SERVER:READ" 96 | ] 97 | } 98 | ] 99 | }, 100 | { 101 | "order": 3, 102 | "title": "Stepper", 103 | "name": "stepper", 104 | "url": "/stepper", 105 | "templateUrl": "project/html/demo/stepper.html", 106 | "requiredPermissions": [ 107 | { 108 | "role": "ADMIN", 109 | "logical": "OR", 110 | "permissions": [ 111 | "DEMO:STEPPER" 112 | ] 113 | }, 114 | { 115 | "role": "ORGADMIN", 116 | "logical": "OR", 117 | "permissions": [ 118 | "DEMO:STEPPER" 119 | ] 120 | }, 121 | { 122 | "role": "USER", 123 | "logical": "OR", 124 | "permissions": [ 125 | "DEMO:STEPPER" 126 | ] 127 | } 128 | ] 129 | }, 130 | { 131 | "order": 4, 132 | "title": "按钮", 133 | "name": "button", 134 | "url": "/button", 135 | "templateUrl": "project/html/demo/buttons.html", 136 | "requiredPermissions": [ 137 | { 138 | "role": "ADMIN", 139 | "logical": "OR", 140 | "permissions": [ 141 | "DEMO:BUTTON" 142 | ] 143 | }, 144 | { 145 | "role": "ORGADMIN", 146 | "logical": "OR", 147 | "permissions": [ 148 | "DEMO:BUTTON" 149 | ] 150 | }, 151 | { 152 | "role": "USER", 153 | "logical": "OR", 154 | "permissions": [ 155 | "DEMO:BUTTON" 156 | ] 157 | } 158 | ] 159 | }, 160 | { 161 | "order": 5, 162 | "title": "树", 163 | "name": "tree", 164 | "url": "/tree", 165 | "templateUrl": "project/html/demo/tree.html", 166 | "requiredPermissions": [ 167 | { 168 | "role": "ADMIN", 169 | "logical": "OR", 170 | "permissions": [ 171 | "DEMO:TREE" 172 | ] 173 | }, 174 | { 175 | "role": "ORGADMIN", 176 | "logical": "OR", 177 | "permissions": [ 178 | "DEMO:TREE" 179 | ] 180 | }, 181 | { 182 | "role": "USER", 183 | "logical": "OR", 184 | "permissions": [ 185 | "DEMO:TREE" 186 | ] 187 | } 188 | ] 189 | }, 190 | { 191 | "order": 6, 192 | "title": "Notification", 193 | "name": "notice", 194 | "url": "/notice", 195 | "templateUrl": "project/html/demo/notification.html", 196 | "requiredPermissions": [ 197 | { 198 | "role": "ADMIN", 199 | "logical": "OR", 200 | "permissions": [ 201 | "DEMO:NOTICE" 202 | ] 203 | }, 204 | { 205 | "role": "ORGADMIN", 206 | "logical": "OR", 207 | "permissions": [ 208 | "DEMO:NOTICE" 209 | ] 210 | }, 211 | { 212 | "role": "USER", 213 | "logical": "OR", 214 | "permissions": [ 215 | "DEMO:NOTICE" 216 | ] 217 | } 218 | ] 219 | }, 220 | { 221 | "order": 7, 222 | "title": "选择添加", 223 | "name": "choose", 224 | "url": "/choose", 225 | "templateUrl": "project/html/demo/choose.html", 226 | "requiredPermissions": [ 227 | { 228 | "role": "ADMIN", 229 | "logical": "OR", 230 | "permissions": [ 231 | "DEMO:CHOOSE" 232 | ] 233 | }, 234 | { 235 | "role": "ORGADMIN", 236 | "logical": "OR", 237 | "permissions": [ 238 | "DEMO:CHOOSE" 239 | ] 240 | }, 241 | { 242 | "role": "USER", 243 | "logical": "OR", 244 | "permissions": [ 245 | "DEMO:CHOOSE" 246 | ] 247 | } 248 | ] 249 | }, 250 | { 251 | "order": 8, 252 | "title": "拖拽", 253 | "name": "drag", 254 | "url": "/drag", 255 | "templateUrl": "project/html/demo/drag.html", 256 | "requiredPermissions": [ 257 | { 258 | "role": "ADMIN", 259 | "logical": "OR", 260 | "permissions": [ 261 | "DEMO:DRAG" 262 | ] 263 | }, 264 | { 265 | "role": "ORGADMIN", 266 | "logical": "OR", 267 | "permissions": [ 268 | "DEMO:DRAG" 269 | ] 270 | }, 271 | { 272 | "role": "USER", 273 | "logical": "OR", 274 | "permissions": [ 275 | "DEMO:DRAG" 276 | ] 277 | } 278 | ] 279 | }, 280 | { 281 | "order": 9, 282 | "title": "流程管理", 283 | "name": "flow_manager", 284 | "url": "/flow", 285 | "templateUrl": "web-public/fit2cloud/html/process/process-management.html", 286 | "requiredPermissions": [ 287 | { 288 | "role": "ADMIN", 289 | "logical": "OR", 290 | "permissions": [ 291 | "FLOW:READ" 292 | ] 293 | } 294 | ] 295 | }, 296 | { 297 | "order": 10, 298 | "title": "文件上传", 299 | "name": "file", 300 | "url": "/file", 301 | "templateUrl": "project/html/demo/file.html", 302 | "requiredPermissions": [ 303 | { 304 | "role": "ADMIN", 305 | "logical": "OR", 306 | "permissions": [ 307 | "DEMO:FILE" 308 | ] 309 | }, 310 | { 311 | "role": "ORGADMIN", 312 | "logical": "OR", 313 | "permissions": [ 314 | "DEMO:FILE" 315 | ] 316 | }, 317 | { 318 | "role": "USER", 319 | "logical": "OR", 320 | "permissions": [ 321 | "DEMO:FILE" 322 | ] 323 | } 324 | ] 325 | }, 326 | { 327 | "order": 11, 328 | "title": "文件上传", 329 | "name": "sidenav", 330 | "url": "/sidenav", 331 | "templateUrl": "project/html/demo/sidenav/sidenav.html", 332 | "requiredPermissions": [ 333 | { 334 | "role": "ADMIN", 335 | "logical": "OR", 336 | "permissions": [ 337 | "DEMO:FILE" 338 | ] 339 | }, 340 | { 341 | "role": "ORGADMIN", 342 | "logical": "OR", 343 | "permissions": [ 344 | "DEMO:FILE" 345 | ] 346 | }, 347 | { 348 | "role": "USER", 349 | "logical": "OR", 350 | "permissions": [ 351 | "DEMO:FILE" 352 | ] 353 | } 354 | ] 355 | } 356 | ] 357 | }, 358 | { 359 | "order": 3, 360 | "title": "示例2", 361 | "icon": "bookmark", 362 | "children": [ 363 | { 364 | "order": 1, 365 | "title": "Loading", 366 | "name": "loading", 367 | "url": "/loading", 368 | "templateUrl": "project/html/demo/loading.html", 369 | "requiredPermissions": [ 370 | { 371 | "role": "ADMIN", 372 | "logical": "OR", 373 | "permissions": [ 374 | "DEMO:LOADING" 375 | ] 376 | }, 377 | { 378 | "role": "ORGADMIN", 379 | "logical": "OR", 380 | "permissions": [ 381 | "DEMO:LOADING" 382 | ] 383 | }, 384 | { 385 | "role": "USER", 386 | "logical": "OR", 387 | "permissions": [ 388 | "DEMO:LOADING" 389 | ] 390 | } 391 | ] 392 | }, 393 | { 394 | "order": 2, 395 | "title": "other", 396 | "name": "other", 397 | "url": "/other", 398 | "templateUrl": "project/html/demo/other.html", 399 | "requiredPermissions": [ 400 | { 401 | "role": "ADMIN", 402 | "logical": "OR", 403 | "permissions": [ 404 | "DEMO:OTHER" 405 | ] 406 | }, 407 | { 408 | "role": "ORGADMIN", 409 | "logical": "OR", 410 | "permissions": [ 411 | "DEMO:OTHER" 412 | ] 413 | }, 414 | { 415 | "role": "USER", 416 | "logical": "OR", 417 | "permissions": [ 418 | "DEMO:OTHER" 419 | ] 420 | } 421 | ] 422 | } 423 | ] 424 | } 425 | ] 426 | } -------------------------------------------------------------------------------- /src/main/java/com/fit2cloud/demo/model/DemoExample.java: -------------------------------------------------------------------------------- 1 | package com.fit2cloud.demo.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class DemoExample { 7 | /** 8 | * This field was generated by MyBatis Generator. 9 | * This field corresponds to the database table demo 10 | * 11 | * @mbg.generated 12 | */ 13 | protected String orderByClause; 14 | 15 | /** 16 | * This field was generated by MyBatis Generator. 17 | * This field corresponds to the database table demo 18 | * 19 | * @mbg.generated 20 | */ 21 | protected boolean distinct; 22 | 23 | /** 24 | * This field was generated by MyBatis Generator. 25 | * This field corresponds to the database table demo 26 | * 27 | * @mbg.generated 28 | */ 29 | protected List oredCriteria; 30 | 31 | /** 32 | * This method was generated by MyBatis Generator. 33 | * This method corresponds to the database table demo 34 | * 35 | * @mbg.generated 36 | */ 37 | public DemoExample() { 38 | oredCriteria = new ArrayList(); 39 | } 40 | 41 | /** 42 | * This method was generated by MyBatis Generator. 43 | * This method corresponds to the database table demo 44 | * 45 | * @mbg.generated 46 | */ 47 | public void setOrderByClause(String orderByClause) { 48 | this.orderByClause = orderByClause; 49 | } 50 | 51 | /** 52 | * This method was generated by MyBatis Generator. 53 | * This method corresponds to the database table demo 54 | * 55 | * @mbg.generated 56 | */ 57 | public String getOrderByClause() { 58 | return orderByClause; 59 | } 60 | 61 | /** 62 | * This method was generated by MyBatis Generator. 63 | * This method corresponds to the database table demo 64 | * 65 | * @mbg.generated 66 | */ 67 | public void setDistinct(boolean distinct) { 68 | this.distinct = distinct; 69 | } 70 | 71 | /** 72 | * This method was generated by MyBatis Generator. 73 | * This method corresponds to the database table demo 74 | * 75 | * @mbg.generated 76 | */ 77 | public boolean isDistinct() { 78 | return distinct; 79 | } 80 | 81 | /** 82 | * This method was generated by MyBatis Generator. 83 | * This method corresponds to the database table demo 84 | * 85 | * @mbg.generated 86 | */ 87 | public List getOredCriteria() { 88 | return oredCriteria; 89 | } 90 | 91 | /** 92 | * This method was generated by MyBatis Generator. 93 | * This method corresponds to the database table demo 94 | * 95 | * @mbg.generated 96 | */ 97 | public void or(Criteria criteria) { 98 | oredCriteria.add(criteria); 99 | } 100 | 101 | /** 102 | * This method was generated by MyBatis Generator. 103 | * This method corresponds to the database table demo 104 | * 105 | * @mbg.generated 106 | */ 107 | public Criteria or() { 108 | Criteria criteria = createCriteriaInternal(); 109 | oredCriteria.add(criteria); 110 | return criteria; 111 | } 112 | 113 | /** 114 | * This method was generated by MyBatis Generator. 115 | * This method corresponds to the database table demo 116 | * 117 | * @mbg.generated 118 | */ 119 | public Criteria createCriteria() { 120 | Criteria criteria = createCriteriaInternal(); 121 | if (oredCriteria.size() == 0) { 122 | oredCriteria.add(criteria); 123 | } 124 | return criteria; 125 | } 126 | 127 | /** 128 | * This method was generated by MyBatis Generator. 129 | * This method corresponds to the database table demo 130 | * 131 | * @mbg.generated 132 | */ 133 | protected Criteria createCriteriaInternal() { 134 | Criteria criteria = new Criteria(); 135 | return criteria; 136 | } 137 | 138 | /** 139 | * This method was generated by MyBatis Generator. 140 | * This method corresponds to the database table demo 141 | * 142 | * @mbg.generated 143 | */ 144 | public void clear() { 145 | oredCriteria.clear(); 146 | orderByClause = null; 147 | distinct = false; 148 | } 149 | 150 | /** 151 | * This class was generated by MyBatis Generator. 152 | * This class corresponds to the database table demo 153 | * 154 | * @mbg.generated 155 | */ 156 | protected abstract static class GeneratedCriteria { 157 | protected List criteria; 158 | 159 | protected GeneratedCriteria() { 160 | super(); 161 | criteria = new ArrayList(); 162 | } 163 | 164 | public boolean isValid() { 165 | return criteria.size() > 0; 166 | } 167 | 168 | public List getAllCriteria() { 169 | return criteria; 170 | } 171 | 172 | public List getCriteria() { 173 | return criteria; 174 | } 175 | 176 | protected void addCriterion(String condition) { 177 | if (condition == null) { 178 | throw new RuntimeException("Value for condition cannot be null"); 179 | } 180 | criteria.add(new Criterion(condition)); 181 | } 182 | 183 | protected void addCriterion(String condition, Object value, String property) { 184 | if (value == null) { 185 | throw new RuntimeException("Value for " + property + " cannot be null"); 186 | } 187 | criteria.add(new Criterion(condition, value)); 188 | } 189 | 190 | protected void addCriterion(String condition, Object value1, Object value2, String property) { 191 | if (value1 == null || value2 == null) { 192 | throw new RuntimeException("Between values for " + property + " cannot be null"); 193 | } 194 | criteria.add(new Criterion(condition, value1, value2)); 195 | } 196 | 197 | public Criteria andIdIsNull() { 198 | addCriterion("id is null"); 199 | return (Criteria) this; 200 | } 201 | 202 | public Criteria andIdIsNotNull() { 203 | addCriterion("id is not null"); 204 | return (Criteria) this; 205 | } 206 | 207 | public Criteria andIdEqualTo(String value) { 208 | addCriterion("id =", value, "id"); 209 | return (Criteria) this; 210 | } 211 | 212 | public Criteria andIdNotEqualTo(String value) { 213 | addCriterion("id <>", value, "id"); 214 | return (Criteria) this; 215 | } 216 | 217 | public Criteria andIdGreaterThan(String value) { 218 | addCriterion("id >", value, "id"); 219 | return (Criteria) this; 220 | } 221 | 222 | public Criteria andIdGreaterThanOrEqualTo(String value) { 223 | addCriterion("id >=", value, "id"); 224 | return (Criteria) this; 225 | } 226 | 227 | public Criteria andIdLessThan(String value) { 228 | addCriterion("id <", value, "id"); 229 | return (Criteria) this; 230 | } 231 | 232 | public Criteria andIdLessThanOrEqualTo(String value) { 233 | addCriterion("id <=", value, "id"); 234 | return (Criteria) this; 235 | } 236 | 237 | public Criteria andIdLike(String value) { 238 | addCriterion("id like", value, "id"); 239 | return (Criteria) this; 240 | } 241 | 242 | public Criteria andIdNotLike(String value) { 243 | addCriterion("id not like", value, "id"); 244 | return (Criteria) this; 245 | } 246 | 247 | public Criteria andIdIn(List values) { 248 | addCriterion("id in", values, "id"); 249 | return (Criteria) this; 250 | } 251 | 252 | public Criteria andIdNotIn(List values) { 253 | addCriterion("id not in", values, "id"); 254 | return (Criteria) this; 255 | } 256 | 257 | public Criteria andIdBetween(String value1, String value2) { 258 | addCriterion("id between", value1, value2, "id"); 259 | return (Criteria) this; 260 | } 261 | 262 | public Criteria andIdNotBetween(String value1, String value2) { 263 | addCriterion("id not between", value1, value2, "id"); 264 | return (Criteria) this; 265 | } 266 | 267 | public Criteria andNameIsNull() { 268 | addCriterion("name is null"); 269 | return (Criteria) this; 270 | } 271 | 272 | public Criteria andNameIsNotNull() { 273 | addCriterion("name is not null"); 274 | return (Criteria) this; 275 | } 276 | 277 | public Criteria andNameEqualTo(String value) { 278 | addCriterion("name =", value, "name"); 279 | return (Criteria) this; 280 | } 281 | 282 | public Criteria andNameNotEqualTo(String value) { 283 | addCriterion("name <>", value, "name"); 284 | return (Criteria) this; 285 | } 286 | 287 | public Criteria andNameGreaterThan(String value) { 288 | addCriterion("name >", value, "name"); 289 | return (Criteria) this; 290 | } 291 | 292 | public Criteria andNameGreaterThanOrEqualTo(String value) { 293 | addCriterion("name >=", value, "name"); 294 | return (Criteria) this; 295 | } 296 | 297 | public Criteria andNameLessThan(String value) { 298 | addCriterion("name <", value, "name"); 299 | return (Criteria) this; 300 | } 301 | 302 | public Criteria andNameLessThanOrEqualTo(String value) { 303 | addCriterion("name <=", value, "name"); 304 | return (Criteria) this; 305 | } 306 | 307 | public Criteria andNameLike(String value) { 308 | addCriterion("name like", value, "name"); 309 | return (Criteria) this; 310 | } 311 | 312 | public Criteria andNameNotLike(String value) { 313 | addCriterion("name not like", value, "name"); 314 | return (Criteria) this; 315 | } 316 | 317 | public Criteria andNameIn(List values) { 318 | addCriterion("name in", values, "name"); 319 | return (Criteria) this; 320 | } 321 | 322 | public Criteria andNameNotIn(List values) { 323 | addCriterion("name not in", values, "name"); 324 | return (Criteria) this; 325 | } 326 | 327 | public Criteria andNameBetween(String value1, String value2) { 328 | addCriterion("name between", value1, value2, "name"); 329 | return (Criteria) this; 330 | } 331 | 332 | public Criteria andNameNotBetween(String value1, String value2) { 333 | addCriterion("name not between", value1, value2, "name"); 334 | return (Criteria) this; 335 | } 336 | 337 | public Criteria andCreateTimeIsNull() { 338 | addCriterion("create_time is null"); 339 | return (Criteria) this; 340 | } 341 | 342 | public Criteria andCreateTimeIsNotNull() { 343 | addCriterion("create_time is not null"); 344 | return (Criteria) this; 345 | } 346 | 347 | public Criteria andCreateTimeEqualTo(Long value) { 348 | addCriterion("create_time =", value, "createTime"); 349 | return (Criteria) this; 350 | } 351 | 352 | public Criteria andCreateTimeNotEqualTo(Long value) { 353 | addCriterion("create_time <>", value, "createTime"); 354 | return (Criteria) this; 355 | } 356 | 357 | public Criteria andCreateTimeGreaterThan(Long value) { 358 | addCriterion("create_time >", value, "createTime"); 359 | return (Criteria) this; 360 | } 361 | 362 | public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) { 363 | addCriterion("create_time >=", value, "createTime"); 364 | return (Criteria) this; 365 | } 366 | 367 | public Criteria andCreateTimeLessThan(Long value) { 368 | addCriterion("create_time <", value, "createTime"); 369 | return (Criteria) this; 370 | } 371 | 372 | public Criteria andCreateTimeLessThanOrEqualTo(Long value) { 373 | addCriterion("create_time <=", value, "createTime"); 374 | return (Criteria) this; 375 | } 376 | 377 | public Criteria andCreateTimeIn(List values) { 378 | addCriterion("create_time in", values, "createTime"); 379 | return (Criteria) this; 380 | } 381 | 382 | public Criteria andCreateTimeNotIn(List values) { 383 | addCriterion("create_time not in", values, "createTime"); 384 | return (Criteria) this; 385 | } 386 | 387 | public Criteria andCreateTimeBetween(Long value1, Long value2) { 388 | addCriterion("create_time between", value1, value2, "createTime"); 389 | return (Criteria) this; 390 | } 391 | 392 | public Criteria andCreateTimeNotBetween(Long value1, Long value2) { 393 | addCriterion("create_time not between", value1, value2, "createTime"); 394 | return (Criteria) this; 395 | } 396 | 397 | public Criteria andSqlCriterion(String value) { 398 | addCriterion("(" + value + ")"); 399 | return (Criteria) this; 400 | } 401 | } 402 | 403 | /** 404 | * This class was generated by MyBatis Generator. 405 | * This class corresponds to the database table demo 406 | * 407 | * @mbg.generated do_not_delete_during_merge 408 | */ 409 | public static class Criteria extends GeneratedCriteria { 410 | 411 | protected Criteria() { 412 | super(); 413 | } 414 | } 415 | 416 | /** 417 | * This class was generated by MyBatis Generator. 418 | * This class corresponds to the database table demo 419 | * 420 | * @mbg.generated 421 | */ 422 | public static class Criterion { 423 | private String condition; 424 | 425 | private Object value; 426 | 427 | private Object secondValue; 428 | 429 | private boolean noValue; 430 | 431 | private boolean singleValue; 432 | 433 | private boolean betweenValue; 434 | 435 | private boolean listValue; 436 | 437 | private String typeHandler; 438 | 439 | public String getCondition() { 440 | return condition; 441 | } 442 | 443 | public Object getValue() { 444 | return value; 445 | } 446 | 447 | public Object getSecondValue() { 448 | return secondValue; 449 | } 450 | 451 | public boolean isNoValue() { 452 | return noValue; 453 | } 454 | 455 | public boolean isSingleValue() { 456 | return singleValue; 457 | } 458 | 459 | public boolean isBetweenValue() { 460 | return betweenValue; 461 | } 462 | 463 | public boolean isListValue() { 464 | return listValue; 465 | } 466 | 467 | public String getTypeHandler() { 468 | return typeHandler; 469 | } 470 | 471 | protected Criterion(String condition) { 472 | super(); 473 | this.condition = condition; 474 | this.typeHandler = null; 475 | this.noValue = true; 476 | } 477 | 478 | protected Criterion(String condition, Object value, String typeHandler) { 479 | super(); 480 | this.condition = condition; 481 | this.value = value; 482 | this.typeHandler = typeHandler; 483 | if (value instanceof List) { 484 | this.listValue = true; 485 | } else { 486 | this.singleValue = true; 487 | } 488 | } 489 | 490 | protected Criterion(String condition, Object value) { 491 | this(condition, value, null); 492 | } 493 | 494 | protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { 495 | super(); 496 | this.condition = condition; 497 | this.value = value; 498 | this.secondValue = secondValue; 499 | this.typeHandler = typeHandler; 500 | this.betweenValue = true; 501 | } 502 | 503 | protected Criterion(String condition, Object value, Object secondValue) { 504 | this(condition, value, secondValue, null); 505 | } 506 | } 507 | } -------------------------------------------------------------------------------- /src/main/resources/static/project/js/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 启动app,加载菜单 3 | */ 4 | 5 | // 流程管理使用方法:1、加载process-design.css和process-design.js,加载f2c.process,配置module.json 6 | var ProjectApp = angular.module('ProjectApp', ['f2c.common', 'f2c.process']); 7 | 8 | // 测试专用 9 | var MENUS_TEST = { 10 | name: "自服务", 11 | icon: "shopping_cart", 12 | menus: [ 13 | { 14 | title: "仪表盘", 15 | icon: "dashboard", 16 | name: "dashboard", 17 | url: "/dashboard", 18 | templateUrl: "project/html/demo/dashboard.html" + '?_t=' + window.appversion 19 | }, 20 | { 21 | title: "示例1", 22 | icon: "assignment", 23 | children: [ 24 | { 25 | title: "表格", 26 | name: "table", 27 | url: "/table", 28 | templateUrl: "project/html/demo/table.html" + '?_t=' + window.appversion 29 | }, { 30 | title: "监控", 31 | name: "metric", 32 | url: "/metric", 33 | templateUrl: "project/html/demo/metric.html" + '?_t=' + window.appversion 34 | }, { 35 | title: "Stepper", 36 | name: "stepper", 37 | url: "/stepper", 38 | templateUrl: "project/html/demo/stepper.html" + '?_t=' + window.appversion 39 | }, { 40 | title: "按钮", 41 | name: "button", 42 | url: "/button", 43 | templateUrl: "project/html/demo/buttons.html" + '?_t=' + window.appversion 44 | }, { 45 | title: "树", 46 | name: "tree", 47 | url: "/tree", 48 | templateUrl: "project/html/demo/tree.html" + '?_t=' + window.appversion 49 | }, { 50 | title: "Notification", 51 | name: "notice", 52 | url: "/notice", 53 | templateUrl: "project/html/demo/notification.html" + '?_t=' + window.appversion 54 | }, { 55 | title: "选择添加", 56 | name: "choose", 57 | url: "/choose", 58 | templateUrl: "project/html/demo/choose.html" + '?_t=' + window.appversion 59 | }, { 60 | title: "拖拽", 61 | name: "drag", 62 | url: "/drag", 63 | templateUrl: "project/html/demo/drag.html" + '?_t=' + window.appversion 64 | }, { 65 | title: "文件", 66 | name: "file", 67 | url: "/file", 68 | templateUrl: "project/html/demo/file.html" + '?_t=' + window.appversion 69 | } 70 | ] 71 | }, 72 | { 73 | title: "示例2", 74 | icon: "assignment", 75 | children: [ 76 | { 77 | title: "Loading", 78 | name: "loading", 79 | url: "/loading", 80 | templateUrl: "project/html/demo/loading.html" + '?_t=' + window.appversion 81 | }, { 82 | title: "other", 83 | name: "other", 84 | url: "/other", 85 | templateUrl: "project/html/demo/other.html" + '?_t=' + window.appversion 86 | } 87 | ] 88 | } 89 | ] 90 | }; 91 | 92 | ProjectApp.controller('DemoCtrl', function ($scope) { 93 | $scope.module = MENUS_TEST; 94 | }); 95 | 96 | ProjectApp.controller('TableCtrl', function ($scope, $mdDialog, $mdBottomSheet, FilterSearch, Notification, HttpUtils, Loading) { 97 | 98 | // 定义搜索条件 99 | $scope.conditions = [ 100 | { 101 | key: "priority", 102 | name: "优先级[有查询,可多选]", 103 | directive: "filter-select-multiple", // 使用哪个指令 104 | selects: [ 105 | {value: 1, label: "选项1"}, 106 | {value: 2, label: "选项2"}, 107 | {value: 3, label: "选项3"}, 108 | {value: 6, label: "其他"} 109 | ], 110 | // 测试select类型条件的搜索框 111 | search: true 112 | }, { 113 | key: "priority", 114 | name: "优先级[有查询]", 115 | directive: "filter-select", // 使用哪个指令 116 | selects: [ 117 | {value: 1, label: "选项1"}, 118 | {value: 2, label: "选项2"}, 119 | {value: 6, label: "其他"} 120 | ], 121 | // 测试select类型条件的搜索框 122 | search: true 123 | }, { 124 | key: "priority", 125 | name: "优先级[无查询]", 126 | directive: "filter-select", 127 | selects: [ 128 | {value: 1, label: "选项1"}, 129 | {value: 2, label: "选项2"}, 130 | {value: 6, label: "其他"} 131 | ] 132 | }, 133 | {key: "no", name: "工单编号", directive: "filter-input"}, 134 | //查询虚机的条件 135 | {key: "instanceName", name: "实例名", directive: "filter-contains"}, 136 | {key: "created", name: "创建日期", directive: "filter-date", directiveUnit: "second"},//directiveUnit: "second"返回时间戳为秒 137 | {key: "os", name: "操作系统", directive: "filter-contains"}, 138 | {key: "localIp", name: "内网IP", directive: "filter-contains"}, 139 | //增加一个异步字典转换的例子,将请求内容转换为value,label格式 140 | { 141 | key: "ajax", 142 | name: "异步字典", 143 | directive: "filter-select-ajax", 144 | url: "demo/status", 145 | convert: {value: "id", label: "name"} 146 | } 147 | 148 | ]; 149 | 150 | // 用于传入后台的参数 151 | $scope.filters = [ 152 | // 设置默认条件default:true(默认条件不会被删掉), 153 | {key: "status", name: "主机状态", value: "Running", label: "运行中", default: true, operator: "="}, 154 | {key: "status", name: "主机状态", value: "Running", default: true, operator: "="}, 155 | {key: "status", name: "主机状态", value: "Running"}, 156 | {key: "status", name: "主机状态", value: "Running"}, 157 | {key: "status", name: "主机状态", value: "Running"}, 158 | {key: "status", name: "主机状态", value: "Running"}, 159 | {key: "status", name: "主机状态", value: "Running"}, 160 | {key: "status", name: "主机状态", value: "Running"}, 161 | {key: "status", name: "主机状态", value: "Running", operator: "="}, 162 | // 可以设置是否显示(display:false不显示,不加display或者display:true则显示) 163 | {key: "status", name: "主机状态", value: "Running", default: true, display: false} 164 | ]; 165 | 166 | // 全选按钮,添加到$scope.columns 167 | $scope.first = { 168 | default: true, 169 | sort: false, 170 | type: "checkbox", 171 | checkValue: false, 172 | change: function (checked) { 173 | $scope.items.forEach(function (item) { 174 | item.enable = checked; 175 | }); 176 | }, 177 | width: "40px" 178 | }; 179 | 180 | $scope.showDetail = function (item) { 181 | // 点击2次关闭 182 | if ($scope.selected === item.$$hashKey) { 183 | $scope.closeInformation(); 184 | return; 185 | } 186 | $scope.selected = item.$$hashKey; 187 | $scope.detail = item; 188 | $scope.showInformation(); 189 | }; 190 | 191 | $scope.closeInformation = function () { 192 | $scope.selected = ""; 193 | $scope.toggleInfoForm(false); 194 | }; 195 | 196 | $scope.showInformation = function () { 197 | $scope.infoUrl = 'project/html/demo/information.html' + '?_t=' + window.appversion; 198 | $scope.toggleInfoForm(true); 199 | }; 200 | 201 | $scope.columns = [ 202 | $scope.first, 203 | {value: "姓名", key: "name", width: "30%"}, 204 | {value: "创建日期", key: "created"}, 205 | {value: "来源", key: "source"}, 206 | {value: "邮箱", key: "email", sort: false},// 不想排序的列,用sort: false 207 | {value: "", default: true} 208 | ]; 209 | 210 | $scope.items = [ 211 | {name: 'demo1', created: '2018-05-14', source: 'fit2cloud', email: 'demo1@fit2cloud.com'}, 212 | {name: 'demo2', created: '2018-05-14', source: 'fit2cloud', email: 'demo2@fit2cloud.com'}, 213 | {name: 'demo3', created: '2018-05-14', source: 'fit2cloud', email: 'demo3@fit2cloud.com'}, 214 | {name: 'demo4', created: '2018-05-14', source: 'fit2cloud', email: 'demo4@fit2cloud.com'} 215 | ]; 216 | 217 | $scope.create = function () { 218 | // $scope.formUrl用于side-form 219 | $scope.formUrl = 'project/html/demo/form.html' + '?_t=' + window.appversion; 220 | // toggleForm由side-form指令生成 221 | $scope.toggleForm(); 222 | }; 223 | 224 | $scope.save = function () { 225 | Notification.show("保存成功", function () { 226 | $scope.toggleForm(); 227 | }); 228 | }; 229 | 230 | $scope.edit = function (item) { 231 | $scope.item = item; 232 | $scope.formUrl = 'project/html/demo/form.html' + '?_t=' + window.appversion; 233 | $scope.toggleForm(); 234 | }; 235 | 236 | $scope.openDialog = function (item, event) { 237 | $scope.item = item; 238 | $mdDialog.show({ 239 | templateUrl: 'project/html/demo/dialog-form.html', 240 | parent: angular.element(document.body), 241 | scope: $scope, 242 | preserveScope: true, 243 | targetEvent: event, 244 | clickOutsideToClose: false 245 | }).then(function (answer) { 246 | $scope.status = 'You said the information was "' + answer + '".'; 247 | }, function () { 248 | $scope.status = 'You cancelled the dialog.'; 249 | }); 250 | }; 251 | 252 | $scope.closeDialog = function () { 253 | $mdDialog.cancel(); 254 | }; 255 | 256 | $scope.ok = function () { 257 | console.log("ok"); 258 | $scope.closeDialog(); 259 | }; 260 | 261 | $scope.pagination = { 262 | page: 1, 263 | total: $scope.items.length, 264 | limits: [10, 20, 50] 265 | }; 266 | 267 | $scope.list = function (sortObj) { 268 | var condition = FilterSearch.convert($scope.filters); 269 | if (sortObj) { 270 | $scope.sort = sortObj; 271 | } 272 | // 保留排序条件,用于分页 273 | if ($scope.sort) { 274 | condition.sort = $scope.sort.sql; 275 | } 276 | 277 | Loading.add(HttpUtils.get("demo/test1/5000", function (response) { 278 | console.log(response); 279 | })); 280 | Loading.add(HttpUtils.get("demo/test1/1000", function (response) { 281 | console.log(response); 282 | })); 283 | // 多个查询用这种方式 284 | $scope.loadingLayer = Loading.load(); 285 | 286 | // 单个查询跟以前一样 287 | $scope.loadingLayer2 = HttpUtils.get("demo/test1/5000", function (response) { 288 | console.log(response); 289 | }) 290 | }; 291 | 292 | // 分页DEMO,有特殊需求可以自定义$scope.pagination,可以只定义一项,比如page:1,其他不写也可以 293 | // OK 294 | // $scope.pagination = { 295 | // page: 1, 296 | // limit: 10, 297 | // limitOptions: [10, 20, 50, 100] 298 | // }; 299 | // OK 300 | // $scope.pagination = { 301 | // page: 2 302 | // }; 303 | HttpUtils.paging($scope, "demo/list", {}); 304 | // 需要callback就加上 305 | HttpUtils.paging($scope, "demo/list", {}, function (response) { 306 | console.log("callback function", $scope.pagination, response); 307 | }); 308 | 309 | $scope.help = function () { 310 | $scope.msg = "Bottom Sheep Demo"; 311 | $mdBottomSheet.show({ 312 | templateUrl: 'project/html/demo/bottom-sheet.html', 313 | scope: $scope, 314 | preserveScope: true 315 | }).then(function (clickedItem) { 316 | $scope.msg = clickedItem['name'] + ' clicked!'; 317 | }).catch(function (error) { 318 | console.log(error) 319 | // User clicked outside or hit escape 320 | }); 321 | } 322 | 323 | }); 324 | 325 | ProjectApp.controller('MetricController', function ($scope) { 326 | var now = new Date().getTime(); 327 | 328 | $scope.request = { 329 | startTime: now - 240 * 3600 * 1000, 330 | endTime: now, 331 | metricDataQueries: [ 332 | { 333 | resourceId: '6d8f69b3-0355-4276-a624-4f57af9d0d85', 334 | resourceName: 'test', 335 | metricSource: "API", 336 | metric: 'SERVER_CPU_USAGE' 337 | } 338 | ] 339 | } 340 | }); 341 | 342 | ProjectApp.controller('WizardController', function ($scope, HttpUtils, Notification) { 343 | // 可用方法$scope.wizard.isLast(),$scope.wizard.isFirst(),$scope.wizard.isSelected(),$scope.wizard.continue() 344 | $scope.wizard = { 345 | setting: { 346 | title: "标题", 347 | subtitle: "子标题", 348 | closeText: "取消", 349 | submitText: "保存", 350 | nextText: "下一步", 351 | prevText: "上一步", 352 | buttons: [ // 去掉buttons,则显示submit按钮 353 | { 354 | text: "自定义按钮", 355 | class: "md-raised md-accent md-hue-2", 356 | click: function () { 357 | Notification.info("自定义按钮 click"); 358 | }, 359 | show: function () { 360 | return $scope.wizard.isLast() || $scope.wizard.current === 2; 361 | }, 362 | disabled: function () { 363 | return $scope.wizard.current === 2; 364 | } 365 | } 366 | ] 367 | }, 368 | // 按顺序显示,id必须唯一并需要与页面中的id一致,select为分步初始化方法,next为下一步方法(最后一步时作为提交方法) 369 | steps: [ 370 | { 371 | id: "1", 372 | name: "云帐号", 373 | select: function () { 374 | console.log("第一步select") 375 | } 376 | }, { 377 | id: "2", 378 | name: "基础设置", 379 | select: function () { 380 | console.log("第二步select") 381 | }, 382 | next: function () { 383 | console.log("第二步Next"); 384 | // 返回true则自动下一步 385 | return true; 386 | } 387 | }, { 388 | id: "3", 389 | name: "异步验证", 390 | select: function () { 391 | console.log("第三步select") 392 | }, 393 | next: function () { 394 | $scope.loadingLayer = HttpUtils.get("demo/test1/2000", function (response) { 395 | console.log("第三步异步验证通过,验证时间:" + response.data); 396 | $scope.wizard.continue(); 397 | }); 398 | // 返回false,则不会自动进行下一步 399 | return false; 400 | } 401 | }, { 402 | id: "4", 403 | name: "权限设置", 404 | select: function () { 405 | console.log("第四步select"); 406 | }, 407 | next: function () { 408 | Notification.confirm("确定保存?", function () { 409 | Notification.info("确定保存"); 410 | }, function () { 411 | Notification.info("取消"); 412 | }) 413 | } 414 | } 415 | ], 416 | // 嵌入页面需要指定关闭方法 417 | close: function () { 418 | $scope.show = false; 419 | } 420 | }; 421 | 422 | $scope.pass = false; 423 | $scope.check = function () { 424 | $scope.pass = !$scope.pass; 425 | }; 426 | 427 | $scope.show = true; 428 | 429 | $scope.open = function () { 430 | $scope.show = true; 431 | } 432 | }); 433 | 434 | ProjectApp.controller('TreeController', function ($scope) { 435 | $scope.option = { 436 | select: "folder" //file, folder, all 437 | }; 438 | $scope.node = { 439 | name: "一级", 440 | collapsed: false, 441 | children: [ 442 | { 443 | name: "二级-1", 444 | children: [ 445 | { 446 | name: "三级-1" 447 | }, { 448 | name: "三级-1" 449 | }, { 450 | name: "三级-1" 451 | }, { 452 | name: "三级-1" 453 | }, { 454 | name: "三级-1" 455 | }, { 456 | name: "三级-1" 457 | }, { 458 | name: "三级-2" 459 | } 460 | ] 461 | }, { 462 | name: "二级-2" 463 | }, { 464 | name: "二级-3", 465 | children: [ 466 | { 467 | name: "三级-3" 468 | }, { 469 | name: "三级-4", 470 | children: [ 471 | { 472 | name: "四级-1" 473 | }, { 474 | name: "四级-2" 475 | } 476 | ] 477 | } 478 | ] 479 | } 480 | ] 481 | }; 482 | 483 | // 也可以用数组 484 | $scope.nodes = [ 485 | { 486 | name: "一级-1", 487 | children: [ 488 | { 489 | name: "二级-1" 490 | }, { 491 | name: "二级-2" 492 | } 493 | ] 494 | }, { 495 | name: "一级-2", 496 | children: [] 497 | }, { 498 | name: "一级-3", 499 | children: [ 500 | { 501 | name: "二级-3" 502 | }, { 503 | name: "二级-4" 504 | } 505 | ] 506 | } 507 | ]; 508 | 509 | // 自动生成$scope.api.getSelected(); 510 | $scope.radio = { 511 | selected: "", 512 | onChange: function (node) { 513 | console.log(node) 514 | } 515 | }; 516 | 517 | // 自动生成$scope.api.getSelected(); 518 | $scope.root = { 519 | onChange: function (node) { 520 | if (node.name === "三级-3") { 521 | let levelTwo = $scope.root.getNode("name", "二级-1"); 522 | if (node.checked) { 523 | $scope.root.toggle(levelTwo, true); 524 | $scope.root.disable(levelTwo, true); 525 | } else { 526 | $scope.root.toggle(levelTwo, false); 527 | $scope.root.disable(levelTwo, false); 528 | } 529 | } 530 | } 531 | }; 532 | 533 | $scope.noroot = {}; 534 | 535 | $scope.getSelected = function () { 536 | console.log("带root", JSON.stringify($scope.root.getSelected(), 4)); 537 | console.log("不带root", JSON.stringify($scope.noroot.getSelected(), 4)); 538 | } 539 | 540 | }); 541 | 542 | ProjectApp.controller('NotificationCtrl', function ($scope, Notification, $mdDialog, $http) { 543 | 544 | $scope.open = function () { 545 | $mdDialog.show({ 546 | templateUrl: 'project/html/switch-source.html', 547 | parent: angular.element(document.body), 548 | scope: $scope, 549 | preserveScope: true, 550 | targetEvent: event, 551 | clickOutsideToClose: false 552 | }); 553 | }; 554 | 555 | 556 | $scope.count = 1; 557 | $scope.show = function () { 558 | var msg = "消息通知" + $scope.count++; 559 | Notification.show(msg); 560 | }; 561 | 562 | $scope.info = function () { 563 | var msg = "消息通知" + $scope.count++; 564 | Notification.info(msg); 565 | }; 566 | 567 | $scope.success = function () { 568 | var msg = "消息通知" + $scope.count++; 569 | Notification.success(msg); 570 | }; 571 | 572 | $scope.warn = function () { 573 | var msg = "消息通知" + $scope.count++; 574 | Notification.warn(msg); 575 | }; 576 | 577 | $scope.danger = function () { 578 | var msg = "消息通知" + $scope.count++; 579 | Notification.danger(msg); 580 | }; 581 | }); 582 | 583 | ProjectApp.controller('ChooseCtrl', function ($scope, HttpUtils) { 584 | $scope.items = [ 585 | {id: 1, name: "长长长长长长长长长长长长长长长长长长长长长长长长长长长看不见"}, 586 | {id: 2, name: "222"}, 587 | {id: 3, name: "333"}, 588 | {id: 4, name: "444"}, 589 | {id: 5, name: "555"}, 590 | {id: 6, name: "666"}, 591 | {id: 7, name: "777"}, 592 | {id: 8, name: "888"} 593 | ]; 594 | 595 | $scope.loadingLayer = HttpUtils.get("demo/test1/2000", function () { 596 | $scope.selected = [3, 4]; 597 | $scope.done = true; 598 | }); 599 | 600 | $scope.selected2 = [ 601 | {id: 1, name: "长长长长长长长长长长长长长长长长长长长长长长长长长长长看不见"}, 602 | {id: 4, name: "444"} 603 | ]; 604 | 605 | $scope.paramList = [ 606 | { 607 | id: "1", 608 | name: "测试1" 609 | }, 610 | { 611 | id: "2", 612 | name: "测试2" 613 | }, { 614 | id: "3", 615 | name: "测试3" 616 | }, { 617 | id: "4", 618 | name: "测试4" 619 | } 620 | ]; 621 | 622 | $scope.item1 = {}; 623 | $scope.item2 = {}; 624 | $scope.item3 = {}; 625 | 626 | $scope.itemList = []; 627 | $scope.itemList.push($scope.item1); 628 | $scope.itemList.push($scope.item2); 629 | $scope.itemList.push($scope.item3); 630 | 631 | }); 632 | 633 | ProjectApp.controller('DragCtrl', function ($scope) { 634 | $scope.items = [ 635 | {id: 1, name: "111"}, 636 | {id: 2, name: "222"}, 637 | {id: 3, name: "333"}, 638 | {id: 4, name: "444"}, 639 | {id: 5, name: "555"}, 640 | {id: 6, name: "666"}, 641 | {id: 7, name: "777"}, 642 | {id: 8, name: "888"} 643 | ]; 644 | 645 | $scope.items2 = [ 646 | {id: 1, name: "111"}, 647 | {id: 2, name: "222"}, 648 | {id: 3, name: "333"}, 649 | {id: 4, name: "444"}, 650 | {id: 5, name: "555"}, 651 | {id: 6, name: "666"}, 652 | {id: 7, name: "777"}, 653 | {id: 8, name: "888"} 654 | ]; 655 | }); 656 | 657 | ProjectApp.filter("dbFilter", function () { 658 | return function (collection, items, item) { 659 | console.log(collection); 660 | console.log(items); 661 | let output = []; 662 | angular.forEach(collection, function (c) { 663 | let flag = true; 664 | angular.forEach(items, function (it) { 665 | if (it.id && it.id.indexOf(c.id) != -1 && !(item.id && item.id.indexOf(c.id) != -1)) { 666 | flag = false; 667 | } 668 | }); 669 | if (flag) { 670 | output.push(c); 671 | } 672 | }); 673 | 674 | return output; 675 | 676 | } 677 | }); 678 | 679 | ProjectApp.controller("SidenavController", function ($scope,$mdSidenav) { 680 | $scope.openSidenav = function () { 681 | $scope.demoUrl = 'project/html/demo/sidenav/sidenav-info.html' + '?_t=' + Math.random(); 682 | $mdSidenav("_side_form_demo_info").toggle(); 683 | }; 684 | 685 | $scope.toggleFormDemoInfo = function () { 686 | $mdSidenav("_side_form_demo_info").toggle(); 687 | } 688 | }); --------------------------------------------------------------------------------